@@ -1758,6 +1758,152 @@ Also see the documentation for `@available
17581758 }];
17591759}
17601760
1761+ def PtrAuthDocs : Documentation {
1762+ let Category = DocCatVariable;
1763+ let Heading = "__ptrauth, __ptrauth_restricted_intptr";
1764+ let Content = [{
1765+ The ``__ptrauth`` qualifier allows the programmer to directly control
1766+ how pointers are signed when they are stored in a particular variable.
1767+ This can be used to strengthen the default protections of pointer
1768+ authentication and make it more difficult for an attacker to escalate
1769+ an ability to alter memory into full control of a process.
1770+
1771+ .. code-block:: c
1772+
1773+ #include <ptrauth.h>
1774+
1775+ typedef void (*my_callback)(const void*);
1776+ my_callback __ptrauth(ptrauth_key_process_dependent_code, 1, 0xe27a) callback;
1777+
1778+ The first argument to ``__ptrauth`` is the name of the signing key.
1779+ Valid key names for the target are defined in ``<ptrauth.h>``.
1780+
1781+ On ARM64, there are four keys:
1782+
1783+ - ``ptrauth_key_process_independent_data``
1784+ - ``ptrauth_key_process_dependent_data``
1785+ - ``ptrauth_key_process_independent_code``
1786+ - ``ptrauth_key_process_dependent_code``
1787+
1788+ In general, prefer using a code key for function pointers and a data key
1789+ for object pointers. The ARM64 architecture allows loads and calls to
1790+ execute more efficiently when the pointer is signed with an appropriate
1791+ key. Using code keys only for function pointers also substantially lessens
1792+ the risk of creating a so-called "signing oracle" for function pointers;
1793+ see the general pointer authentication language documentation.
1794+
1795+ Using a process-dependent key provides stronger protection against
1796+ cross-process attacks. However, it also inhibits certain memory
1797+ optimizations when a shared library is loaded into multiple processes.
1798+ Using a process-independent key also allows signed pointers to be passed
1799+ in shared memory. Note that even the process-independent keys may change
1800+ after a reboot, so signed values should never be serialized.
1801+
1802+ The second argument to ``__ptrauth`` is a flag (0 or 1) specifying whether
1803+ the object should use address discrimination. If only one argument is
1804+ given, the flag defaults to 0. Address discrimination provides strong
1805+ protection against attacks which copy signed pointers around in memory.
1806+ An attacker cannot usefully copy an arbitrary signed pointer over an
1807+ address-discriminated object. Nor can a value taken from an
1808+ address-discriminated object be usefully copied over some other signed
1809+ pointer. However, it is more expensive to copy values from one
1810+ address-discriminated object to another, even if the other arguments to
1811+ ``__ptrauth`` are the same, and it is not valid to copy them with
1812+ ``memcpy``. It is also not valid to map memory containing an
1813+ address-discriminated object into different places in the address
1814+ space, e.g. with ``mmap``.
1815+
1816+ The third argument to ``__ptrauth`` is a small non-negative integer
1817+ which allows additional discrimination between objects. Using a
1818+ unique extra discriminator provides strong protection against attacks
1819+ which work by substituting one signed value for another. For example,
1820+ an attacker cannot usefully overwrite an object with a pointer from an
1821+ object using a different extra discriminator; this protection is similar
1822+ to the protection offered by address discrimination. A unique extra
1823+ discriminator also protects against "slide" attacks where an attacker
1824+ alters a pointer instead of altering the memory that the pointer points to.
1825+ The extra discriminator must be a constant expression. On ARM64,
1826+ its value must be between 0 and 65535. If the argument is not provided,
1827+ the default value is 0. It is generally preferable not to use the value 0,
1828+ especially with the process-independent keys, as this combination is used
1829+ in various places in the standard language ABI.
1830+
1831+ The type qualified by ``__ptrauth`` must be a pointer type. Currently
1832+ only C pointer types are allowed and not block pointers, Objective-C
1833+ object pointers, or C++ references. ``__ptrauth`` is parsed and interpreted
1834+ using the same language rules as qualifiers like ``const`` and ``volatile``.
1835+ For example:
1836+
1837+ .. code-block:: c
1838+
1839+ __ptrauth(...) int *ex0; /* invalid: qualifies 'int', which is not a pointer type */
1840+ int * __ptrauth(...) ex1; /* valid: ex1 has qualified type */
1841+ int * __ptrauth(...) *ex2; /* valid: ex2 is a pointer to a qualified object */
1842+
1843+ typedef int *intp;
1844+ __ptrauth(...) intp ex3; /* valid: ex3 has qualified type */
1845+ intp __ptrauth(...) ex4; /* valid: means the exact same thing as ex3 */
1846+
1847+ If a ``__ptrauth``-qualified l-value of function pointer type is
1848+ used as the function operand of a call expression, the function pointer
1849+ will be authenticated "atomically" with the call, such that an attacker
1850+ will not be able to corrupt the destination of the call even in the
1851+ presence of undefined behavior. (That is, the compiler must not
1852+ leave an un-signed pointer that it will later unconditionally trust
1853+ in a place where it could be feasibly overwritten by an attacker,
1854+ such as the stack or a callee-save register during an intervening call.
1855+ The compiler is not required to protect against improbable attacks
1856+ such as corruption of the register file, as might occur with a
1857+ corrupted kernel. It also need not guard against jumps to an arbitrary
1858+ place in the instruction stream, since such jumps would require an
1859+ attacker to already fully control the PC.)
1860+
1861+ If the ABI specifies that a pointer is always signed --- that is,
1862+ if the pointer is a function pointer and the target uses ABI function
1863+ pointer authentication --- then signing and authenticating it as part
1864+ of a load/store actually means resigning it to/from the standard ABI
1865+ signature schema. Similarly, if both operands of a simple assignment
1866+ operator are ``__ptrauth``-qualified, the pointer copied by the
1867+ assignment is resigned from the right-hand operand's schema to the
1868+ left-hand operand's schema. These resigning operations are also done
1869+ "atomically" in the same sense as above.
1870+
1871+ As a final guarantee, if the right-hand operand of an assignment or
1872+ the expression used to initialize a ``__ptrauth``-qualified object is
1873+ a direct reference to an object or function (e.g. ``&my_var``), the
1874+ signing of that pointer is atomic with the evaluaton of the reference
1875+ in this same sense.
1876+
1877+ Otherwise, there are no guarantees of atomicity, and it is the
1878+ programmer's responsibility to avoid allowing a store into a
1879+ ``__ptrauth``-qualified object to create a potential "signing oracle"
1880+ which an attacker could use to sign an arbitrary pointer of their choice.
1881+ Such oracles are particularly problematic when the signing uses a code
1882+ key because the oracle could potentially be used to allow an attacker
1883+ to construct a validly-signed function pointer, v-table entry, or
1884+ return address that points to an arbitrary instruction, allowing them
1885+ to completely take over the PC. Programmers attempting to use
1886+ ``__ptrauth`` to protect a data pointer, or to protect function pointers
1887+ on targets that do not use ABI function pointer authentication, should
1888+ aim to maintain a "chain of authentication" from initialization all
1889+ the way to the point at which the pointer is used. If this is infeasible,
1890+ they should consider using ``ptrauth_sign_generic_data`` instead.
1891+
1892+ Types that are written in r-value positions, such as return types,
1893+ parameter types, and cast types, may not be ``__ptrauth``-qualified
1894+ at the outermost level. This may be supported in the future.
1895+
1896+ In C++, the arguments to ``__ptrauth`` may not be instantiation-dependent.
1897+ This may be supported in the future.
1898+
1899+ This feature may be tested for with ``__has_feature(ptrauth_qualifier)``.
1900+ It is enabled whenever the ``ptrauth`` intrinsics are enabled.
1901+
1902+ ``<ptrauth.h>`` provides predefined qualifiers for various language
1903+ features that implicitly use pointer authentication.
1904+ }];
1905+ }
1906+
17611907def ExternalSourceSymbolDocs : Documentation {
17621908 let Category = DocCatDecl;
17631909 let Content = [{
0 commit comments