[clang] [NFC][Clang][Docs] Update Pointer Authentication documentation (PR #152596)
Oliver Hunt via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 13 18:04:30 PDT 2025
================
@@ -255,33 +260,160 @@ signing schema breaks down even more simply:
It is important that the signing schema be independently derived at all signing
and authentication sites. Preferably, the schema should be hard-coded
everywhere it is needed, but at the very least, it must not be derived by
-inspecting information stored along with the pointer.
+inspecting information stored along with the pointer. See the section on
+`Attacks on pointer authentication`_ for more information.
+
-Language Features
+Language features
-----------------
-There is currently one main pointer authentication language feature:
+There are three levels of the pointer authentication language feature:
+
+- The language implementation automatically signs and authenticates function
+ pointers (and certain data pointers) across a variety of standard situations,
+ including return addresses, function pointers, and C++ virtual functions. The
+ intent is for all pointers to code in program memory to be signed in some way
+ and for all branches to code in program text to authenticate those
+ signatures.
+
+- The language also provides extensions to override the default rules used by
+ the language implementation. For example, the ``__ptrauth`` type qualifier
+ can be used to change how pointers are signed when they are stored in
+ a particular variable or field; this provides much stronger protection than
+ is guaranteed by the default rules for C function and data pointers.
-- The language provides the ``<ptrauth.h>`` intrinsic interface for manually
- signing and authenticating pointers in code. These can be used in
+- Finally, the language provides the ``<ptrauth.h>`` intrinsic interface for
+ manually signing and authenticating pointers in code. These can be used in
circumstances where very specific behavior is required.
+Language implementation
+~~~~~~~~~~~~~~~~~~~~~~~
+
+For the most part, pointer authentication is an unobserved detail of the
+implementation of the programming language. Any element of the language
+implementation that would perform an indirect branch to a pointer is implicitly
+altered so that the pointer is signed when first constructed and authenticated
+when the branch is performed. This includes:
+
+- indirect-call features in the programming language, such as C function
+ pointers, C++ virtual functions, C++ member function pointers, the "blocks"
+ C extension, and so on;
+
+- returning from a function, no matter how it is called; and
+
+- indirect calls introduced by the implementation, such as branches through the
+ global offset table (GOT) used to implement direct calls to functions defined
+ outside of the current shared object.
+
+For more information about this, see the `Language ABI`_ section.
+
+However, some aspects of the implementation are observable by the programmer or
+otherwise require special notice.
+
+C data pointers
+^^^^^^^^^^^^^^^
+
+The current implementation in Clang does not sign pointers to ordinary data by
+default. For a partial explanation of the reasoning behind this, see the
+`Theory of Operation`_ section.
+
+A specific data pointer which is more security-sensitive than most can be
+signed using the `__ptrauth qualifier`_ or using the ``<ptrauth.h>``
+intrinsics.
+
+C function pointers
+^^^^^^^^^^^^^^^^^^^
-Language Extensions
+The C standard imposes restrictions on the representation and semantics of
+function pointer types which make it difficult to achieve satisfactory
+signature diversity in the default language rules. See `Attacks on pointer
+authentication`_ for more information about signature diversity. Programmers
+should strongly consider using the ``__ptrauth`` qualifier to improve the
+protections for important function pointers, such as the components of of
+a hand-rolled "v-table"; see the section on the `__ptrauth qualifier`_ for
+details.
+
+The value of a pointer to a C function includes a signature, even when the
+value is cast to a non-function-pointer type like ``void*`` or ``intptr_t``. On
+implementations that use high bits to store the signature, this means that
+relational comparisons and hashes will vary according to the exact signature
+value, which is likely to change between executions of a program. In some
+implementations, it may also vary based on the exact function pointer type.
+
+Null pointers
+^^^^^^^^^^^^^
+
+In principle, an implementation could derive the signed null pointer value
+simply by applying the standard signing algorithm to the raw null pointer
+value. However, for likely signing algorithms, this would mean that the signed
+null pointer value would no longer be statically known, which would have many
+negative consequences. For one, it would become substantially more expensive
+to emit null pointer values or to perform null-pointer checks. For another,
+the pervasive (even if technically unportable) assumption that null pointers
+are bitwise zero would be invalidated, making it substantially more difficult
+to adopt pointer authentication, as well as weakening common optimizations for
+zero-initialized memory such as the use of ``.bzz`` sections. Therefore it is
+beneficial to treat null pointers specially by giving them their usual
+representation. On AArch64, this requires additional code when working with
+possibly-null pointers, such as when copying a pointer field that has been
+signed with address diversity.
+
+While this representation of nulls is the safest option for the general case,
+there are some situations in which a null pointer may have important semantic
+or security impact. For that purpose clang has the concept of a pointer
----------------
ojhunt wrote:
definitely pushed now
https://github.com/llvm/llvm-project/pull/152596
More information about the cfe-commits
mailing list