Compiler Attributes: Add __kcfi_salt
Kees Cook
maintainerPATCH 1/1 Compiler Attributes: Add __kcfi_salt
Add support for Clang's coming "kcfi_salt" attribute, which is designed to allow for KCFI prototype hashes to be separated[1]. For example, normally two "void func(void)" functions would have the same KCFI hash, but if they wanted their indirect calls to be distinguishable by KCFI, one could add __kcfi_salt("foo").
To test the result, add a corresponding LKDTM test, CFI_FORWARD_SALT.
---
Cc: Bill Wendling <[email protected]>
Cc: Andrew Cooper <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Miguel Ojeda <[email protected]>
Cc: Nathan Chancellor <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Cc: Justin Stitt <[email protected]>
Cc: <[email protected]>
--- include/linux/compiler_attributes.h | 11 +++++++++++ drivers/misc/lkdtm/cfi.c | 27 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+)
include/linux/compiler_attributes.h +11 -0
@@ -164,6 +164,17 @@*/ #define __gnu_inline __attribute__((__gnu_inline__)) +/* +* Optional: not supported by gcc +* +* clang: https://clang.llvm.org/docs/AttributeReference.html#kcfi-salt +*/ +#if __has_attribute (__kcfi_salt__) +# define __kcfi_salt (STR ) __attribute__((__kcfi_salt__(STR))) +#else +# define __kcfi_salt (STR ) +#endif +/* * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute * clang: https://clang.llvm.org/docs/AttributeReference.html#malloc
drivers/misc/lkdtm/cfi.c +27 -0
@@ -21,6 +21,13 @@ static noinline int lkdtm_increment_int(int *counter)return *counter; } +/* Function matching prototype of lkdtm_increment_int but separate salt. */ +static noinline __kcfi_salt("separate prototype hash") +void lkdtm_increment_void_again (int *counter) +{ + (*counter)++; +} +/* Don't allow the compiler to inline the calls. */ static noinline void lkdtm_indirect_call(void (*func)(int *)) {
@@ -46,6 +53,25 @@ static void lkdtm_CFI_FORWARD_PROTO(void)pr_expected_config (CONFIG_CFI_CLANG ); } +/* +* This tries to call an indirect function with a mismatched hash salt. +*/ +static void lkdtm_CFI_FORWARD_SALT (void ) +{ +/* +* Matches lkdtm_increment_void()'s and lkdtm_increment_void_again()'s +* prototypes, but they have different hash salts. +*/ +pr_info ("Calling matched prototype ...\n" ); +lkdtm_indirect_call (lkdtm_increment_void); + +pr_info ("Calling mismatched hash salt ...\n" ); +lkdtm_indirect_call (lkdtm_increment_void_again); + +pr_err ("FAIL: survived mismatched salt function call!\n" ); +pr_expected_config (CONFIG_CFI_CLANG ); +} +/* * This can stay local to LKDTM, as there should not be a production reason * to disable PAC && SCS.
@@ -193,6 +219,7 @@ static void lkdtm_CFI_BACKWARD(void)static struct crashtype crashtypes[] = {CRASHTYPE (CFI_FORWARD_PROTO ), +CRASHTYPE (CFI_FORWARD_SALT ),CRASHTYPE (CFI_BACKWARD ), };
Signature · 1 line
2.34.1
Quoted 6 lines · Kees Cook
Add support for Clang's coming "
kcfi_salt" attribute, which is designed to allow for KCFI prototype hashes to be separated[1]. For example, normally two "void func(void)" functions would have the same KCFI hash, but if they wanted their indirect calls to be distinguishable by KCFI, one could add__kcfi_salt("foo").
It would be nice to have a quick sentence inline summarizing how it will be used, e.g. what kind of functions will need to be annotated.
Quoted 1 line
To test the result, add a corresponding LKDTM test,
CFI_FORWARD_SALT.
Sounds good.
Quoted 1 line
+ * clang: https://clang.llvm.org/docs/AttributeReference.html#kcfi-salt
I guess this anchor will eventually work -- I see you asked about it at:
https://github.com/llvm/llvm-project/pull/141846#discussion_r2209236363
From what I see, this still has to land in LLVM, right? So I guess there is still time to land this (and the discussion started years ago), but if you need to take it quickly as a base for some other work or similar:
Cheers,
Miguel
Quoted 3 lines · Miguel Ojeda
It would be nice to have a quick sentence inline summarizing how it will be used, e.g. what kind of functions will need to be annotated.
By the way, related to the use case question: would we eventually want such an attribute for Rust too? If so, happy to help.
Cheers,
Miguel
Quoted 9 lines · Miguel Ojeda
Quoted 3 lines · Miguel Ojeda
It would be nice to have a quick sentence inline summarizing how it will be used, e.g. what kind of functions will need to be annotated.
By the way, related to the use case question: would we eventually want such an attribute for Rust too? If so, happy to help.
I would definitely like to see Rust support for this too. Otherwise, we would have to drop the attribute when Rust is enabled to avoid CFI type mismatches with C code.
Sami
Quoted 4 lines · Sami Tolvanen
I would definitely like to see Rust support for this too. Otherwise, we would have to drop the attribute when Rust is enabled to avoid CFI type mismatches with C code.
Thanks for confirming -- added then to:
https://github.com/Rust-for-Linux/linux/issues/354
I will ask upstream when it lands in LLVM.
Cheers,
Miguel
Hi Kees,
Quoted 8 lines · Kees Cook
drivers/misc/lkdtm/cfi.c +7
-0+/* +* This tries to call an indirect function with a mismatched hash salt. +*/ +static void lkdtm_CFI_FORWARD_SALT (void ) +{ +/* +* Matches lkdtm_increment_void()'s and lkdtm_increment_void_again()'s
drivers/misc/lkdtm/cfi.c static void lkdtm_CFI_FORWARD_PROTO(void) · line 72
Quoted 10 lines
drivers/misc/lkdtm/cfi.c +10
-0+* prototypes, but they have different hash salts. +*/ +pr_info ("Calling matched prototype ...\n" ); +lkdtm_indirect_call (lkdtm_increment_void); + +pr_info ("Calling mismatched hash salt ...\n" ); +lkdtm_indirect_call (lkdtm_increment_void_again); + +pr_err ("FAIL: survived mismatched salt function call!\n" ); +pr_expected_config (CONFIG_CFI_CLANG );
Should this test also have a "This is probably expected" message if the compiler doesn't support the __kcfi_salt__ attribute?
Sami