@@ -3648,67 +3648,87 @@ def CFISaltDocs : Documentation {
36483648 let Heading = "cfi_salt";
36493649 let Label = "langext-cfi_salt";
36503650 let Content = [{
3651- Use ``__attribute__((cfi_salt("<salt>")))`` on a function declaration, function
3652- definition, or typedef to help distinguish CFI hashes between functions with
3653- the same type signature. Take, for example, the Linux kernel, where there are
3654- hundreds of functions with the same type signature that are indirectly
3655- callable.
3651+ The ``cfi_salt`` attribute allows you to add a salt value to Control Flow
3652+ Integrity (CFI) type hashes to help distinguish between functions with the
3653+ same type signature. This attribute can be applied to function declarations,
3654+ function definitions, and function pointer typedefs.
36563655
3657- .. code-block::
3658-
3659- 1662 functions with void (*)(void)
3660- 1179 functions with int (*)(void)
3661- ...
3656+ **Syntax:**
36623657
3663- Making the CFI value distinct between them allows CFI to be more robust.
3658+ * GNU-style: ``__attribute__((cfi_salt("<salt_string>")))`
3659+ * C++11-style: ``[[clang::cfi_salt("<salt_string>")]]``
36643660
3665- Example use:
3661+ **Usage:**
36663662
3667- .. code-block:: c
3663+ The attribute takes a single string literal argument that serves as the salt.
3664+ Functions or function types with different salt values will have different CFI
3665+ hashes, even if they have identical type signatures.
36683666
3669- // .h file:
3670- #define __cfi_salt __attribute__((cfi_salt("pepper")))
3667+ **Motivation:**
36713668
3672- // Convenient typedefs to avoid nested declarator syntax.
3673- typedef int (*fptr_t)(void); // Non-salted function call.
3674- typedef int (*fptr_salted_t)(void) __cfi_salt;
3669+ In large codebases like the Linux kernel, there are often hundreds of functions
3670+ with identical type signatures that are called indirectly:
36753671
3676- struct widget_generator {
3677- fptr_t init;
3678- fptr_salted_t exec;
3679- fptr_t teardown;
3680- };
3672+ .. code-block::
36813673
3682- // 1st .c file:
3683- static int internal_init(void) { /* ... */ }
3684- static int internal_salted_exec(void) __cfi_salt { /* ... */ }
3685- static int internal_teardown(void) { /* ... */ }
3674+ 1662 functions with void (*)(void)
3675+ 1179 functions with int (*)(void)
3676+ ...
36863677
3687- static struct widget_generator _generator = {
3688- .init = internal_init,
3689- .exec = internal_salted_exec,
3690- .teardown = internal_teardown,
3691- };
3678+ By salting the CFI hashes, you can make CFI more robust by ensuring that
3679+ functions intended for different purposes have distinct CFI identities.
36923680
3693- struct widget_generator *widget_gen = &_generator;
3681+ **Type Compatibility:**
36943682
3695- // 2nd .c file:
3696- int generate_a_widget(void) {
3697- int ret;
3683+ * Functions with different salt values are considered to have incompatible types
3684+ * Function pointers with different salt values cannot be assigned to each other
3685+ * All declarations of the same function must use the same salt value
36983686
3699- // Called with non-salted CFI.
3700- ret = widget_gen->init();
3701- if (ret)
3702- return ret;
3687+ **Example:**
37033688
3704- // Called with salted CFI.
3705- ret = widget_gen->exec();
3706- if (ret)
3707- return ret;
3689+ .. code-block:: c
37083690
3709- // Called with non-salted CFI.
3710- return widget_gen->teardown();
3711- }
3691+ // Header file - define convenience macros
3692+ #define __cfi_salt(s) __attribute__((cfi_salt(s)))
3693+
3694+ // Typedef for regular function pointers
3695+ typedef int (*fptr_t)(void);
3696+
3697+ // Typedef for salted function pointers
3698+ typedef int (*fptr_salted_t)(void) __cfi_salt("pepper");
3699+
3700+ struct widget_ops {
3701+ fptr_t init; // Regular CFI
3702+ fptr_salted_t exec; // Salted CFI
3703+ fptr_t cleanup; // Regular CFI
3704+ };
3705+
3706+ // Function implementations
3707+ static int widget_init(void) { return 0; }
3708+ static int widget_exec(void) __cfi_salt("pepper") { return 1; }
3709+ static int widget_cleanup(void) { return 0; }
3710+
3711+ static struct widget_ops ops = {
3712+ .init = widget_init, // OK - compatible types
3713+ .exec = widget_exec, // OK - both use "pepper" salt
3714+ .cleanup = widget_cleanup // OK - compatible types
3715+ };
3716+
3717+ // Using C++11 attribute syntax
3718+ void secure_callback(void) [[clang::cfi_salt("secure")]];
3719+
3720+ // This would cause a compilation error:
3721+ // fptr_t bad_ptr = widget_exec; // Error: incompatible types
3722+
3723+ **Notes:**
3724+
3725+ * The salt string can contain any characters, including spaces and quotes
3726+ * This attribute only applies to function types; using it on non-function
3727+ types will generate a warning
3728+ * All declarations and definitions of the same function must use identical
3729+ salt values
3730+ * The attribute affects type compatibility during compilation and CFI hash
3731+ generation during code generation
37123732
37133733 }];
37143734}
0 commit comments