-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][PAC] add support for options parameter to __ptrauth #136828
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
927380b
02bc476
5903e97
ef4a253
6b1501a
96a81fa
31aa3a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -283,7 +283,7 @@ a number of different tests. | |||||
__ptrauth Qualifier | ||||||
^^^^^^^^^^^^^^^^^^^ | ||||||
|
||||||
``__ptrauth(key, address, discriminator)`` is an extended type | ||||||
``__ptrauth(key, address, discriminator, options)`` is an extended type | ||||||
qualifier which causes so-qualified objects to hold pointers or pointer sized | ||||||
integers signed using the specified schema rather than the default schema for | ||||||
such types. | ||||||
|
@@ -303,6 +303,9 @@ The qualifier's operands are as follows: | |||||
|
||||||
- ``discriminator`` - a constant discriminator; must be a constant expression | ||||||
|
||||||
- ``options`` - a constant string expression containing a list of comma | ||||||
separated authentication options; see ``ptrauth_qualifier_options``_ | ||||||
|
||||||
See `Discriminators`_ for more information about discriminators. | ||||||
|
||||||
Currently the operands must be constant-evaluable even within templates. In the | ||||||
|
@@ -314,9 +317,9 @@ qualifiers on a parameter (after parameter type adjustment) are ignored when | |||||
deriving the type of the function. The parameter will be passed using the | ||||||
default ABI for the unqualified pointer type. | ||||||
|
||||||
If ``x`` is an object of type ``__ptrauth(key, address, discriminator) T``, | ||||||
then the signing schema of the value stored in ``x`` is a key of ``key`` and | ||||||
a discriminator determined as follows: | ||||||
If ``x`` is an object of type ``__ptrauth(key, address, discriminator, options) T``, | ||||||
then the signing schema of the value stored in ``x`` is a key of ``key`` and a | ||||||
discriminator determined as follows: | ||||||
|
||||||
- if ``address`` is 0, then the discriminator is ``discriminator``; | ||||||
|
||||||
|
@@ -327,6 +330,27 @@ a discriminator determined as follows: | |||||
is ``ptrauth_blend_discriminator(&x, discriminator)``; see | ||||||
`ptrauth_blend_discriminator`_. | ||||||
|
||||||
``ptrauth_qualifier_options`` | ||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||||||
|
||||||
The options parameter to the ``__ptrauth`` qualifier is a string of comma | ||||||
separated modifiers to the normal authentication behavior. Currently supported | ||||||
options are | ||||||
|
||||||
- Authentication mode: This is one of ``strip``, ``sign-and-strip``, and | ||||||
``sign-and-auth``. The ability to modify this behavior is intended to support | ||||||
staging ABI changes. The ``strip`` mode results in the PAC bits of a value | ||||||
being stripped from any value and disabled any other authentication | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
operations. ``sign-and-strip`` strips an authenticated on read, but will | ||||||
ensure a correct signature is set on assignment. Finally ``sign-and-auth`` is | ||||||
the default mode, and provides full protection for the value. | ||||||
|
||||||
- ``authenticates-null-values``: By default the __ptrauth qualifier does not | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
sign the zero value. This permits fast implementation of null checks in the | ||||||
common case where a null value is safe. The ``authenticates-null-values`` | ||||||
option overrides this behavior, and permits null values to be protected with | ||||||
pointer authentication. | ||||||
|
||||||
``<ptrauth.h>`` | ||||||
~~~~~~~~~~~~~~~ | ||||||
|
||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -65,6 +65,17 @@ enum class PointerAuthenticationMode : unsigned { | |
SignAndAuth | ||
}; | ||
|
||
static constexpr llvm::StringLiteral PointerAuthenticationOptionStrip = "strip"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cor3ntin @AaronBallman is there a better/more idiomatic way of doing these? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the language option level, I think it's more idiomatic to use an enumeration instead of string literals and doing string processing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd suggest doing a string-switch on it, then storing an enum in the AST. We can then print it/whatever on the way out. But a pair of conversion functions is typically all you should need. Though, it doesn't seem that these are leaving the Either way, LangOpts is a little bit of an odd place for this to live. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not stored as a string (or even an attribute), they're stored as flags and enums in the pointer auth qualifier on the type. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was meaning "is there a more idiomatic way to have these string constants specified?" :D There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, I hadn't included the updated to stringifying the qualifier so these were only used in one place. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Usually we'd do what @erichkeane was suggesting -- not have these as constants in LangOptions.h but instead have helper functions which convert string -> enum -> string. Then these strings can be hidden within a .cpp file rather than exposed in a header with broader visibility. WDYT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah so what @erichkeane was suggesting is that places needing the string would do std::string myString = get_the_string_for(thEnum) Though that still leaves me with "where should these functions and enums live?" It really does not seem like LangOpts is right |
||
static constexpr llvm::StringLiteral PointerAuthenticationOptionSignAndStrip = | ||
"sign-and-strip"; | ||
static constexpr llvm::StringLiteral PointerAuthenticationOptionSignAndAuth = | ||
"sign-and-auth"; | ||
static constexpr llvm::StringLiteral PointerAuthenticationOptionIsaPointer = | ||
"isa-pointer"; | ||
static constexpr llvm::StringLiteral | ||
PointerAuthenticationOptionAuthenticatesNullValues = | ||
"authenticates-null-values"; | ||
|
||
/// Bitfields of LangOptions, split out from LangOptions in order to ensure that | ||
/// this large collection of bitfields is a trivial class type. | ||
class LangOptionsBase { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR does not actually provide the implementation of this option, as it touches a number of places unrelated to parsing the option.