@@ -1778,129 +1778,11 @@ an ability to alter memory into full control of a process.
17781778The first argument to ``__ptrauth`` is the name of the signing key.
17791779Valid key names for the target are defined in ``<ptrauth.h>``.
17801780
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-
18021781The 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``.
1782+ the object should use address discrimination.
18151783
18161784The 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.
1785+ which allows additional discrimination between objects.
19041786 }];
19051787}
19061788
0 commit comments