Skip to content

Commit 44950cc

Browse files
committed
Reject function protos that have different cfi_salt values.
1 parent cec156a commit 44950cc

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11441,6 +11441,11 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
1144111441
if (lproto->getMethodQuals() != rproto->getMethodQuals())
1144211442
return {};
1144311443

11444+
// Function protos with different 'cfi_salt' values aren't compatible.
11445+
if (lproto->getExtraAttributeInfo().CFISalt !=
11446+
rproto->getExtraAttributeInfo().CFISalt)
11447+
return {};
11448+
1144411449
// Function effects are handled similarly to noreturn, see above.
1144511450
FunctionEffectsRef LHSFX = lproto->getFunctionEffects();
1144611451
FunctionEffectsRef RHSFX = rproto->getFunctionEffects();

clang/lib/Sema/SemaType.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7947,6 +7947,10 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state, ParsedAttr &attr,
79477947
if (!S.checkStringLiteralArgumentAttr(attr, 0, Argument))
79487948
return false;
79497949

7950+
// Delay if this is not a function type.
7951+
if (!unwrapped.isFunctionType())
7952+
return false;
7953+
79507954
const auto *FnTy = unwrapped.get()->getAs<FunctionProtoType>();
79517955
FunctionProtoType::ExtProtoInfo EPI = FnTy->getExtProtoInfo();
79527956
EPI.ExtraAttributeInfo.CFISalt = Argument;

clang/test/Sema/attr-cfi-salt.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %clang_cc1 -fsyntax-only -fsanitize=kcfi -verify %s
2+
3+
#define __cfi_salt(S) __attribute__((cfi_salt(S)))
4+
5+
int foo(int a, int b) __cfi_salt("pepper"); // ok
6+
int foo(int a, int b) __cfi_salt("pepper"); // ok
7+
8+
typedef int (*bar_t)(void) __cfi_salt("pepper"); // ok
9+
typedef int (*bar_t)(void) __cfi_salt("pepper"); // ok
10+
11+
#if 0
12+
// FIXME: These should fail.
13+
int b(void) __cfi_salt("salt 'n") __cfi_salt("pepper");
14+
bar_t bar_fn __cfi_salt("salt 'n");
15+
#endif
16+
17+
int baz __cfi_salt("salt");
18+
// expected-warning@-1{{'cfi_salt' only applies to function types}}
19+
20+
int baz_fn(int a, int b) __cfi_salt("salt 'n");
21+
// expected-note@-1{{previous declaration is here}}
22+
int baz_fn(int a, int b) __cfi_salt("pepper");
23+
// expected-error@-1{{conflicting types for 'baz_fn'}}
24+
25+
int mux_fn(int a, int b) __cfi_salt("salt 'n");
26+
// expected-note@-1{{previous declaration is here}}
27+
int mux_fn(int a, int b) __cfi_salt("pepper") {
28+
// expected-error@-1{{conflicting types for 'mux_fn'}}
29+
return a * b;
30+
}
31+
32+
typedef int qux_t __cfi_salt("salt");
33+
// expected-warning@-1{{'cfi_salt' only applies to function types}}
34+
35+
typedef int (*quux_t)(void) __cfi_salt("salt 'n");
36+
// expected-note@-1{{previous definition is here}}
37+
typedef int (*quux_t)(void) __cfi_salt("pepper");
38+
// expected-error@-1{{typedef redefinition with different type}}

0 commit comments

Comments
 (0)