Skip to content

Commit c8048c7

Browse files
pdherbemonthaoNoQ
authored andcommitted
[attributes] Generalize attribute 'enforce_tcb' to Objective-C methods.
Calling an ObjC method from a C function marked with the 'enforce_tcb' attribute did not produce a warning. Now it does, and on top of that Objective-C methods can participate in TCBs themselves. Differential Revision: https://reviews.llvm.org/D122343
1 parent 1721d52 commit c8048c7

File tree

6 files changed

+154
-15
lines changed

6 files changed

+154
-15
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3915,15 +3915,15 @@ def Builtin : InheritableAttr {
39153915

39163916
def EnforceTCB : InheritableAttr {
39173917
let Spellings = [Clang<"enforce_tcb">];
3918-
let Subjects = SubjectList<[Function]>;
3918+
let Subjects = SubjectList<[Function, ObjCMethod]>;
39193919
let Args = [StringArgument<"TCBName">];
39203920
let Documentation = [EnforceTCBDocs];
39213921
bit InheritEvenIfAlreadyPresent = 1;
39223922
}
39233923

39243924
def EnforceTCBLeaf : InheritableAttr {
39253925
let Spellings = [Clang<"enforce_tcb_leaf">];
3926-
let Subjects = SubjectList<[Function]>;
3926+
let Subjects = SubjectList<[Function, ObjCMethod]>;
39273927
let Args = [StringArgument<"TCBName">];
39283928
let Documentation = [EnforceTCBLeafDocs];
39293929
bit InheritEvenIfAlreadyPresent = 1;

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12988,7 +12988,8 @@ class Sema final {
1298812988
/// attempts to add itself into the container
1298912989
void CheckObjCCircularContainer(ObjCMessageExpr *Message);
1299012990

12991-
void CheckTCBEnforcement(const CallExpr *TheCall, const FunctionDecl *Callee);
12991+
void CheckTCBEnforcement(const SourceLocation CallExprLoc,
12992+
const NamedDecl *Callee);
1299212993

1299312994
void AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE);
1299412995
void AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,

clang/lib/Sema/SemaChecking.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5497,7 +5497,9 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
54975497
if (!FnInfo)
54985498
return false;
54995499

5500-
CheckTCBEnforcement(TheCall, FDecl);
5500+
// Enforce TCB except for builtin calls, which are always allowed.
5501+
if (FDecl->getBuiltinID() == 0)
5502+
CheckTCBEnforcement(TheCall->getExprLoc(), FDecl);
55015503

55025504
CheckAbsoluteValueFunction(TheCall, FDecl);
55035505
CheckMaxUnsignedZero(TheCall, FDecl);
@@ -5537,6 +5539,8 @@ bool Sema::CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation lbrac,
55375539
/*IsMemberFunction=*/false, lbrac, Method->getSourceRange(),
55385540
CallType);
55395541

5542+
CheckTCBEnforcement(lbrac, Method);
5543+
55405544
return false;
55415545
}
55425546

@@ -17359,13 +17363,11 @@ ExprResult Sema::SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall,
1735917363
/// CheckTCBEnforcement - Enforces that every function in a named TCB only
1736017364
/// directly calls other functions in the same TCB as marked by the enforce_tcb
1736117365
/// and enforce_tcb_leaf attributes.
17362-
void Sema::CheckTCBEnforcement(const CallExpr *TheCall,
17363-
const FunctionDecl *Callee) {
17364-
const FunctionDecl *Caller = getCurFunctionDecl();
17366+
void Sema::CheckTCBEnforcement(const SourceLocation CallExprLoc,
17367+
const NamedDecl *Callee) {
17368+
const NamedDecl *Caller = getCurFunctionOrMethodDecl();
1736517369

17366-
// Calls to builtins are not enforced.
17367-
if (!Caller || !Caller->hasAttr<EnforceTCBAttr>() ||
17368-
Callee->getBuiltinID() != 0)
17370+
if (!Caller || !Caller->hasAttr<EnforceTCBAttr>())
1736917371
return;
1737017372

1737117373
// Search through the enforce_tcb and enforce_tcb_leaf attributes to find
@@ -17383,9 +17385,8 @@ void Sema::CheckTCBEnforcement(const CallExpr *TheCall,
1738317385
[&](const auto *A) {
1738417386
StringRef CallerTCB = A->getTCBName();
1738517387
if (CalleeTCBs.count(CallerTCB) == 0) {
17386-
this->Diag(TheCall->getExprLoc(),
17387-
diag::warn_tcb_enforcement_violation) << Callee
17388-
<< CallerTCB;
17388+
this->Diag(CallExprLoc, diag::warn_tcb_enforcement_violation)
17389+
<< Callee << CallerTCB;
1738917390
}
1739017391
});
1739117392
}

clang/test/Misc/pragma-attribute-supported-attributes-list.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@
6161
// CHECK-NEXT: DisableSanitizerInstrumentation (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
6262
// CHECK-NEXT: DisableTailCalls (SubjectMatchRule_function, SubjectMatchRule_objc_method)
6363
// CHECK-NEXT: EnableIf (SubjectMatchRule_function)
64-
// CHECK-NEXT: EnforceTCB (SubjectMatchRule_function)
65-
// CHECK-NEXT: EnforceTCBLeaf (SubjectMatchRule_function)
64+
// CHECK-NEXT: EnforceTCB (SubjectMatchRule_function, SubjectMatchRule_objc_method)
65+
// CHECK-NEXT: EnforceTCBLeaf (SubjectMatchRule_function, SubjectMatchRule_objc_method)
6666
// CHECK-NEXT: EnumExtensibility (SubjectMatchRule_enum)
6767
// CHECK-NEXT: Error (SubjectMatchRule_function)
6868
// CHECK-NEXT: ExcludeFromExplicitInstantiation (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s
2+
3+
int foo();
4+
5+
__attribute__((objc_root_class))
6+
@interface AClass
7+
- (void)bothTCBAndTCBLeafOnSeparateRedeclarations __attribute__((enforce_tcb("x"))); // expected-note{{conflicting attribute is here}}
8+
9+
- (void)bothTCBAndTCBLeafOnSeparateRedeclarationsOppositeOrder __attribute__((enforce_tcb_leaf("x"))); // expected-note{{conflicting attribute is here}}
10+
11+
- (void)bothTCBAndTCBLeafButDifferentIdentifiersOnSeparateRedeclarations __attribute__((enforce_tcb("x")));
12+
13+
- (void)bothTCBAndTCBLeafButDifferentIdentifiersOnSeparateRedeclarationsOppositeOrder __attribute__((enforce_tcb_leaf("x")));
14+
15+
- (void)onInterfaceOnly __attribute__((enforce_tcb("test")));
16+
@end
17+
18+
@interface AClass (NoImplementation)
19+
- (void)noArguments __attribute__((enforce_tcb)); // expected-error{{'enforce_tcb' attribute takes one argument}}
20+
21+
- (void)tooManyArguments __attribute__((enforce_tcb("test", 12))); // expected-error{{'enforce_tcb' attribute takes one argument}}
22+
23+
- (void)wrongArgumentType __attribute__((enforce_tcb(12))); // expected-error{{'enforce_tcb' attribute requires a string}}
24+
25+
- (void)noArgumentsLeaf __attribute__((enforce_tcb_leaf)); // expected-error{{'enforce_tcb_leaf' attribute takes one argument}}
26+
27+
- (void)tooManyArgumentsLeaf __attribute__((enforce_tcb_leaf("test", 12))); // expected-error{{'enforce_tcb_leaf' attribute takes one argument}}
28+
29+
- (void)wrongArgumentTypeLeaf __attribute__((enforce_tcb_leaf(12))); // expected-error{{'enforce_tcb_leaf' attribute requires a string}}
30+
@end
31+
32+
@implementation AClass
33+
- (void)onInterfaceOnly {
34+
foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'test'}}
35+
}
36+
37+
- (void)bothTCBAndTCBLeaf
38+
__attribute__((enforce_tcb("x")))
39+
__attribute__((enforce_tcb_leaf("x"))) // expected-error{{attributes 'enforce_tcb_leaf("x")' and 'enforce_tcb("x")' are mutually exclusive}}
40+
{
41+
foo(); // no-warning
42+
}
43+
44+
- (void)bothTCBAndTCBLeafOnSeparateRedeclarations
45+
__attribute__((enforce_tcb_leaf("x"))) // expected-error{{attributes 'enforce_tcb_leaf("x")' and 'enforce_tcb("x")' are mutually exclusive}}
46+
{
47+
// Error recovery: no need to emit a warning when we didn't
48+
// figure out our attributes to begin with.
49+
foo(); // no-warning
50+
}
51+
52+
- (void)bothTCBAndTCBLeafOppositeOrder
53+
__attribute__((enforce_tcb_leaf("x")))
54+
__attribute__((enforce_tcb("x"))) // expected-error{{attributes 'enforce_tcb("x")' and 'enforce_tcb_leaf("x")' are mutually exclusive}}
55+
{
56+
foo(); // no-warning
57+
}
58+
59+
- (void)bothTCBAndTCBLeafOnSeparateRedeclarationsOppositeOrder
60+
__attribute__((enforce_tcb("x"))) // expected-error{{attributes 'enforce_tcb("x")' and 'enforce_tcb_leaf("x")' are mutually exclusive}}
61+
{
62+
foo(); // no-warning
63+
}
64+
65+
- (void)bothTCBAndTCBLeafButDifferentIdentifiers
66+
__attribute__((enforce_tcb("x")))
67+
__attribute__((enforce_tcb_leaf("y"))) // no-error
68+
{
69+
foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'x'}}
70+
}
71+
72+
- (void)bothTCBAndTCBLeafButDifferentIdentifiersOppositeOrder
73+
__attribute__((enforce_tcb_leaf("x")))
74+
__attribute__((enforce_tcb("y"))) // no-error
75+
{
76+
foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'y'}}
77+
}
78+
79+
- (void)bothTCBAndTCBLeafButDifferentIdentifiersOnSeparateRedeclarations
80+
__attribute__((enforce_tcb_leaf("y"))) // no-error
81+
{
82+
foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'x'}}
83+
}
84+
85+
- (void)bothTCBAndTCBLeafButDifferentIdentifiersOnSeparateRedeclarationsOppositeOrder
86+
__attribute__((enforce_tcb("y"))) {
87+
foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'y'}}
88+
}
89+
90+
- (void)errorRecoveryOverIndividualTCBs
91+
__attribute__((enforce_tcb("y")))
92+
__attribute__((enforce_tcb("x")))
93+
__attribute__((enforce_tcb_leaf("x"))) // expected-error{{attributes 'enforce_tcb_leaf("x")' and 'enforce_tcb("x")' are mutually exclusive}}
94+
{
95+
// FIXME: Ideally this should warn. The conflict between attributes
96+
// for TCB "x" shouldn't affect the warning about TCB "y".
97+
foo(); // no-warning
98+
}
99+
100+
@end

clang/test/Sema/attr-enforce-tcb.m

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify %s
2+
3+
#define PLACE_IN_TCB(NAME) __attribute__((enforce_tcb(NAME)))
4+
#define PLACE_IN_TCB_LEAF(NAME) __attribute__((enforce_tcb_leaf(NAME)))
5+
6+
__attribute__((objc_root_class))
7+
@interface AClass
8+
@property(readonly) id propertyNotInAnyTCB;
9+
@end
10+
11+
@implementation AClass
12+
- (void)inTCBFoo PLACE_IN_TCB("foo") {
13+
[self notInAnyTCB]; // expected-warning{{calling 'notInAnyTCB' is a violation of trusted computing base 'foo'}}
14+
}
15+
- (void)inTCBFooAsLeaf PLACE_IN_TCB_LEAF("foo") {
16+
[self notInAnyTCB]; // no-warning
17+
}
18+
- (void)notInAnyTCB {
19+
}
20+
+ (void)classMethodNotInAnyTCB {
21+
}
22+
+ (void)classMethodInTCBFoo PLACE_IN_TCB("foo") {
23+
[self inTCBFoo]; // no-warning
24+
[self inTCBFooAsLeaf]; // no-warning
25+
[self notInAnyTCB]; // expected-warning{{calling 'notInAnyTCB' is a violation of trusted computing base 'foo'}}
26+
}
27+
@end
28+
29+
PLACE_IN_TCB("foo")
30+
void call_objc_method(AClass *object) {
31+
[object inTCBFoo]; // no-warning
32+
[object inTCBFooAsLeaf]; // no-warning
33+
[object notInAnyTCB]; // expected-warning{{calling 'notInAnyTCB' is a violation of trusted computing base 'foo'}}
34+
[AClass classMethodNotInAnyTCB]; // expected-warning{{calling 'classMethodNotInAnyTCB' is a violation of trusted computing base 'foo'}}
35+
[AClass classMethodInTCBFoo]; // no-warning
36+
(void)object.propertyNotInAnyTCB; // expected-warning{{calling 'propertyNotInAnyTCB' is a violation of trusted computing base 'foo'}}
37+
}

0 commit comments

Comments
 (0)