llvm-project/clang/test/Sema/attr-enforce-tcb-errors.cpp
Sean Dooher 35c9baa11e [attributes] Add a facility for enforcing a Trusted Computing Base.
Introduce a function attribute 'enforce_tcb' that prevents the function
from calling other functions without the same attribute. This allows
isolating code that's considered to be somehow privileged so that it could not
use its privileges to exhibit arbitrary behavior.

Introduce an on-by-default warning '-Wtcb-enforcement' that warns
about violations of the above rule.

Introduce a function attribute 'enforce_tcb_leaf' that suppresses
the new warning within the function it is attached to. Such leaf functions
may implement common functionality between the trusted and the untrusted code
but they require extra careful audit with respect to their capabilities.

Fixes after a revert in 419ef38a50293c58078f830517f5e305068dbee6:
Fix a test.
Add workaround for GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67274).
Attribute the patch appropriately!

Differential Revision: https://reviews.llvm.org/D91898
2021-01-11 10:20:51 -08:00

81 lines
4.0 KiB
C++

// RUN: %clang_cc1 -fsyntax-only -verify %s
[[clang::enforce_tcb("oops")]] int wrong_subject_type; // expected-warning{{'enforce_tcb' attribute only applies to functions}}
void no_arguments() __attribute__((enforce_tcb)); // expected-error{{'enforce_tcb' attribute takes one argument}}
void too_many_arguments() __attribute__((enforce_tcb("test", 12))); // expected-error{{'enforce_tcb' attribute takes one argument}}
void wrong_argument_type() __attribute__((enforce_tcb(12))); // expected-error{{'enforce_tcb' attribute requires a string}}
[[clang::enforce_tcb_leaf("oops")]] int wrong_subject_type_leaf; // expected-warning{{'enforce_tcb_leaf' attribute only applies to functions}}
void no_arguments_leaf() __attribute__((enforce_tcb_leaf)); // expected-error{{'enforce_tcb_leaf' attribute takes one argument}}
void too_many_arguments_leaf() __attribute__((enforce_tcb_leaf("test", 12))); // expected-error{{'enforce_tcb_leaf' attribute takes one argument}}
void wrong_argument_type_leaf() __attribute__((enforce_tcb_leaf(12))); // expected-error{{'enforce_tcb_leaf' attribute requires a string}}
void foo();
__attribute__((enforce_tcb("x")))
__attribute__((enforce_tcb_leaf("x"))) // expected-error{{attributes 'enforce_tcb_leaf("x")' and 'enforce_tcb("x")' are mutually exclusive}}
void both_tcb_and_tcb_leaf() {
foo(); // no-warning
}
__attribute__((enforce_tcb_leaf("x"))) // expected-note{{conflicting attribute is here}}
void both_tcb_and_tcb_leaf_on_separate_redeclarations();
__attribute__((enforce_tcb("x"))) // expected-error{{attributes 'enforce_tcb("x")' and 'enforce_tcb_leaf("x")' are mutually exclusive}}
void both_tcb_and_tcb_leaf_on_separate_redeclarations() {
// Error recovery: no need to emit a warning when we didn't
// figure out our attributes to begin with.
foo(); // no-warning
}
__attribute__((enforce_tcb_leaf("x")))
__attribute__((enforce_tcb("x"))) // expected-error{{attributes 'enforce_tcb("x")' and 'enforce_tcb_leaf("x")' are mutually exclusive}}
void both_tcb_and_tcb_leaf_opposite_order() {
foo(); // no-warning
}
__attribute__((enforce_tcb("x"))) // expected-note{{conflicting attribute is here}}
void both_tcb_and_tcb_leaf_on_separate_redeclarations_opposite_order();
__attribute__((enforce_tcb_leaf("x"))) // expected-error{{attributes 'enforce_tcb_leaf("x")' and 'enforce_tcb("x")' are mutually exclusive}}
void both_tcb_and_tcb_leaf_on_separate_redeclarations_opposite_order() {
foo(); // no-warning
}
__attribute__((enforce_tcb("x")))
__attribute__((enforce_tcb_leaf("y"))) // no-error
void both_tcb_and_tcb_leaf_but_different_identifiers() {
foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'x'}}
}
__attribute__((enforce_tcb_leaf("x")))
__attribute__((enforce_tcb("y"))) // no-error
void both_tcb_and_tcb_leaf_but_different_identifiers_opposite_order() {
foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'y'}}
}
__attribute__((enforce_tcb("x")))
void both_tcb_and_tcb_leaf_but_different_identifiers_on_separate_redeclarations();
__attribute__((enforce_tcb_leaf("y"))) // no-error
void both_tcb_and_tcb_leaf_but_different_identifiers_on_separate_redeclarations() {
foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'x'}}
}
__attribute__((enforce_tcb_leaf("x")))
void both_tcb_and_tcb_leaf_but_different_identifiers_on_separate_redeclarations_opposite_order();
__attribute__((enforce_tcb("y")))
void both_tcb_and_tcb_leaf_but_different_identifiers_on_separate_redeclarations_opposite_order() {
foo(); // expected-warning{{calling 'foo' is a violation of trusted computing base 'y'}}
}
__attribute__((enforce_tcb("y")))
__attribute__((enforce_tcb("x")))
__attribute__((enforce_tcb_leaf("x"))) // expected-error{{attributes 'enforce_tcb_leaf("x")' and 'enforce_tcb("x")' are mutually exclusive}}
void error_recovery_over_individual_tcbs() {
// FIXME: Ideally this should warn. The conflict between attributes
// for TCB "x" shouldn't affect the warning about TCB "y".
foo(); // no-warning
}