diff options
author | Bill Wendling <morbo@google.com> | 2025-08-14 13:07:38 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-08-14 13:07:38 -0700 |
commit | aa4805a09052c1b6298718eeb6d30c33dd0d695f (patch) | |
tree | b9c2bf308e852f38c24b9f1f9eda317cb3997092 /clang/lib/CodeGen/CodeGenModule.h | |
parent | 5479b7ed4200a85de3aa9335110883a86715811d (diff) | |
download | llvm-aa4805a09052c1b6298718eeb6d30c33dd0d695f.zip llvm-aa4805a09052c1b6298718eeb6d30c33dd0d695f.tar.gz llvm-aa4805a09052c1b6298718eeb6d30c33dd0d695f.tar.bz2 |
[Clang][attr] Add 'cfi_salt' attribute (#141846)
The 'cfi_salt' attribute specifies a string literal that is used as a
"salt" for Control-Flow Integrity (CFI) checks to distinguish between
functions with the same type signature. This attribute can be applied
to function declarations, function definitions, and function pointer
typedefs.
This attribute prevents function pointers from being replaced with
pointers to functions that have a compatible type, which can be a CFI
bypass vector.
The attribute affects type compatibility during compilation and CFI
hash generation during code generation.
Attribute syntax: [[clang::cfi_salt("<salt_string>")]]
GNU-style syntax: __attribute__((cfi_salt("<salt_string>")))
- The attribute takes a single string of non-NULL ASCII characters.
- It only applies to function types; using it on a non-function type
will generate an error.
- All function declarations and the function definition must include
the attribute and use identical salt values.
Example usage:
// Header file:
#define __cfi_salt(S) __attribute__((cfi_salt(S)))
// Convenient typedefs to avoid nested declarator syntax.
typedef int (*fp_unsalted_t)(void);
typedef int (*fp_salted_t)(void) __cfi_salt("pepper");
struct widget_ops {
fp_unsalted_t init; // Regular CFI.
fp_salted_t exec; // Salted CFI.
fp_unsalted_t teardown; // Regular CFI.
};
// bar.c file:
static int bar_init(void) { ... }
static int bar_salted_exec(void) __cfi_salt("pepper") { ... }
static int bar_teardown(void) { ... }
static struct widget_generator _generator = {
.init = bar_init,
.exec = bar_salted_exec,
.teardown = bar_teardown,
};
struct widget_generator *widget_gen = _generator;
// 2nd .c file:
int generate_a_widget(void) {
int ret;
// Called with non-salted CFI.
ret = widget_gen.init();
if (ret)
return ret;
// Called with salted CFI.
ret = widget_gen.exec();
if (ret)
return ret;
// Called with non-salted CFI.
return widget_gen.teardown();
}
Link: https://github.com/ClangBuiltLinux/linux/issues/1736
Link: https://github.com/KSPP/linux/issues/365
---------
Signed-off-by: Bill Wendling <morbo@google.com>
Co-authored-by: Aaron Ballman <aaron@aaronballman.com>
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.h')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index cb013fe..705d9a3 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1621,7 +1621,7 @@ public: llvm::ConstantInt *CreateCrossDsoCfiTypeId(llvm::Metadata *MD); /// Generate a KCFI type identifier for T. - llvm::ConstantInt *CreateKCFITypeId(QualType T); + llvm::ConstantInt *CreateKCFITypeId(QualType T, StringRef Salt); /// Create a metadata identifier for the given type. This may either be an /// MDString (for external identifiers) or a distinct unnamed MDNode (for |