aaron.ballman added a comment.

In D91898#2413004 <https://reviews.llvm.org/D91898#2413004>, @NoQ wrote:

>> if the TCB-based functions are a small subset of the code then this 
>> attribute is better
>
> Yes, that's exactly the case. We want most functions to be untrusted by 
> default but also have no restrictions imposed or warnings emitted for them 
> when they do their usual function things.

Excellent, thank you both for considering it!



================
Comment at: clang/include/clang/Basic/Attr.td:3585
+def EnforceTCB : InheritableAttr {
+  let Spellings = [GCC<"enforce_tcb">];
+  let Subjects = SubjectList<[Function]>;
----------------
I don't think GCC supports these attributes, so this spelling should probably 
be `Clang` rather than `GCC`.


================
Comment at: clang/include/clang/Basic/AttrDocs.td:5497
+  called from a function with the enforce_tcb attribute. A function may be
+  a part of multiple TCBs. Invocations of function pointers and C++ methods
+  are not checked. Builtins are considered to a part of every TCB.
----------------
Are there plans to support this on function pointers or other kinds of callable 
things?

Also, it seems rather odd that C++ methods are not checked. I could somewhat 
understand not checking virtual functions, but why not member functions where 
the target is known? Why not static member functions?


================
Comment at: clang/include/clang/Basic/DiagnosticGroups.td:1246
+
+def TCBEnforcement : DiagGroup<"tcb-enforcement">;
----------------
Are you planning on adding more diagnostics under this group? If not, I'd 
suggest defining it inline (see below).


================
Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:11052
+def warn_tcb_enforcement_violation : Warning<
+  "TCB [%0] has been violated by calling a function [%1] that is not in the 
TCB.">,
+  InGroup<TCBEnforcement>;
----------------



================
Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:11053
+  "TCB [%0] has been violated by calling a function [%1] that is not in the 
TCB.">,
+  InGroup<TCBEnforcement>;
 } // end of sema component.
----------------
...assuming the group won't be reused by too many diagnostics.


================
Comment at: clang/include/clang/Sema/Sema.h:12454
 
+  void CheckTCBEnforcement(CallExpr *TheCall,  FunctionDecl *Callee);
+
----------------
Can you make these `const` pointers?


================
Comment at: clang/lib/Sema/SemaChecking.cpp:16070
+void Sema::CheckTCBEnforcement(CallExpr *TheCall,  FunctionDecl *Callee) {
+  FunctionDecl *Caller = getCurFunctionDecl();
+
----------------



================
Comment at: clang/lib/Sema/SemaChecking.cpp:16072
+
+  // Calls to builtins are not enforced
+  if (!Caller || !Caller->hasAttr<EnforceTCBAttr>() || Callee->getBuiltinID() 
!= 0) {
----------------



================
Comment at: clang/lib/Sema/SemaChecking.cpp:16073-16075
+  if (!Caller || !Caller->hasAttr<EnforceTCBAttr>() || Callee->getBuiltinID() 
!= 0) {
+    return;
+  }
----------------



================
Comment at: clang/lib/Sema/SemaChecking.cpp:16079-16084
+  for (const auto *Attr : Callee->specific_attrs<EnforceTCBAttr>()) {
+    CalleeTCBs.insert(Attr->getTCBName());
+  }
+  for (const auto *Attr : Callee->specific_attrs<EnforceTCBLeafAttr>()) {
+    CalleeTCBs.insert(Attr->getTCBName());
+  }
----------------
Pretty sure you can remove the manual loops here with something like this.


================
Comment at: clang/lib/Sema/SemaChecking.cpp:16086
+
+  // Go through the TCBs the caller is a part of and emit warnings if Caller 
is in a TCB that the Callee is not
+  for (const auto *Attr : Caller->specific_attrs<EnforceTCBAttr>()) {
----------------
Can you be sure to run the patch through clang-format, this looks like it's 
over the 80 col limit.


================
Comment at: clang/lib/Sema/SemaChecking.cpp:16088
+  for (const auto *Attr : Caller->specific_attrs<EnforceTCBAttr>()) {
+    llvm::StringRef CallerTCB = Attr->getTCBName();
+
----------------



================
Comment at: clang/lib/Sema/SemaChecking.cpp:16090-16092
+    if (CalleeTCBs.count(CallerTCB) == 0) {
+      Diag(TheCall->getExprLoc(), diag::warn_tcb_enforcement_violation) << 
CallerTCB << Callee->getName();
+    }
----------------



================
Comment at: clang/lib/Sema/SemaDeclAttr.cpp:7339
 
+template<typename Attr>
+static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
----------------



================
Comment at: clang/lib/Sema/SemaDeclAttr.cpp:7344
+    return;
+  D->addAttr(Attr::Create(S.Context, Argument, AL));
+}
----------------



================
Comment at: clang/test/Sema/attr-enforce-tcb.c:1
+// RUN: %clang_cc1  -fsyntax-only -verify %s
+
----------------



================
Comment at: clang/test/Sema/attr-enforce-tcb.c:15
+void foo9 (void);
+
+void
----------------
Some more interesting tests:
```
// Ensure that attribute merging works as expected across redeclarations.
void foo10() PLACE_IN_TCB("baz");
void foo10() PLACE_IN_TCB("bar");
void foo10() PLACE_IN_TCB("quux");

// Ensure that attribute instantiation works as expected.
template <typename Ty>
void foo11(Ty) PLACE_IN_TCB("bar");

// Basic checks
void foo12(void) __attribute__((enforce_tcb(12))); // wrong arg type
[[clang::enforce_tcb("oops")]] int foo13; // Wrong subject type
void foo14(void) __attribute__((enforce_tcb)); // Wrong number of arguments
void foo15(void) __attribute__((enforce_tcb("test", 12)); // Wrong number of 
arguments
// Add similar basic checks for enforce_tcb_leaf.
```


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D91898/new/

https://reviews.llvm.org/D91898

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to