[llvm] [clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff f9aba820eb6478a617145eb690ba8b06490d7ac5 c4e7c86eb967b4313e19587e33fdc6b50c8cd6a7 -- clang/lib/Headers/ptrauth.h clang/test/CodeGen/ptrauth-intrinsics.c clang/test/Preprocessor/ptrauth_feature.c clang/test/Sema/ptrauth-intrinsics-macro.c clang/test/Sema/ptrauth.c clang/include/clang/Basic/TargetInfo.h clang/include/clang/Sema/Sema.h clang/lib/Basic/TargetInfo.cpp clang/lib/Basic/Targets/AArch64.cpp clang/lib/Basic/Targets/AArch64.h clang/lib/CodeGen/CGBuiltin.cpp clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Frontend/CompilerInvocation.cpp clang/lib/Sema/SemaChecking.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 2e1a687c39..5e7c5bf247 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -4969,7 +4969,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__builtin_ptrauth_sign_unauthenticated: case Builtin::BI__builtin_ptrauth_strip: { // Emit the arguments. -SmallVector args; +SmallVector args; for (auto argExpr : E->arguments()) args.push_back(EmitScalarExpr(argExpr)); @@ -4979,25 +4979,25 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, args[0] = Builder.CreatePtrToInt(args[0], IntPtrTy); switch (BuiltinID) { - case Builtin::BI__builtin_ptrauth_auth_and_resign: -if (args[4]->getType()->isPointerTy()) - args[4] = Builder.CreatePtrToInt(args[4], IntPtrTy); -LLVM_FALLTHROUGH; - - case Builtin::BI__builtin_ptrauth_auth: - case Builtin::BI__builtin_ptrauth_sign_unauthenticated: -if (args[2]->getType()->isPointerTy()) - args[2] = Builder.CreatePtrToInt(args[2], IntPtrTy); -break; +case Builtin::BI__builtin_ptrauth_auth_and_resign: + if (args[4]->getType()->isPointerTy()) +args[4] = Builder.CreatePtrToInt(args[4], IntPtrTy); + LLVM_FALLTHROUGH; + +case Builtin::BI__builtin_ptrauth_auth: +case Builtin::BI__builtin_ptrauth_sign_unauthenticated: + if (args[2]->getType()->isPointerTy()) +args[2] = Builder.CreatePtrToInt(args[2], IntPtrTy); + break; - case Builtin::BI__builtin_ptrauth_sign_generic_data: -if (args[1]->getType()->isPointerTy()) - args[1] = Builder.CreatePtrToInt(args[1], IntPtrTy); -break; +case Builtin::BI__builtin_ptrauth_sign_generic_data: + if (args[1]->getType()->isPointerTy()) +args[1] = Builder.CreatePtrToInt(args[1], IntPtrTy); + break; - case Builtin::BI__builtin_ptrauth_blend_discriminator: - case Builtin::BI__builtin_ptrauth_strip: -break; +case Builtin::BI__builtin_ptrauth_blend_discriminator: +case Builtin::BI__builtin_ptrauth_strip: + break; } // Call the intrinsic. diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 402f117976..8cd02a6430 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -7077,7 +7077,6 @@ void Clang::ConstructJob(Compilation , const JobAction , options::OPT_fno_ptrauth_intrinsics, false)) CmdArgs.push_back("-fptrauth-intrinsics"); - // -fsigned-bitfields is default, and clang doesn't yet support // -funsigned-bitfields. if (!Args.hasFlag(options::OPT_fsigned_bitfields, diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h index 5061c8298f..de656abddf 100644 --- a/clang/lib/Headers/ptrauth.h +++ b/clang/lib/Headers/ptrauth.h @@ -67,8 +67,7 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; The value must be an expression of pointer type. The key must be a constant expression of type ptrauth_key. The result will have the same type as the original value. */ -#define ptrauth_strip(__value, __key) \ - __builtin_ptrauth_strip(__value, __key) +#define ptrauth_strip(__value, __key) __builtin_ptrauth_strip(__value, __key) /* Blend a constant discriminator into the given pointer-like value to form a new discriminator. Not all bits of the inputs are @@ -80,7 +79,7 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; The first argument must be an expression of pointer type. The second argument must be an expression of integer type. The result will have type uintptr_t. */ -#define ptrauth_blend_discriminator(__pointer, __integer) \ +#define ptrauth_blend_discriminator(__pointer, __integer) \ __builtin_ptrauth_blend_discriminator(__pointer, __integer) /* Add a signature to the given pointer value using a specific key, @@ -95,7 +94,7 @@ typedef __UINTPTR_TYPE__
[llvm] [clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha updated https://github.com/llvm/llvm-project/pull/65996 >From c4e7c86eb967b4313e19587e33fdc6b50c8cd6a7 Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Wed, 16 Aug 2023 09:17:12 -0700 Subject: [PATCH] [AArch64][PAC] Support and document ptrauth builtins and -fptrauth-intrinsics. This defines the basic set of pointer authentication clang builtins (provided in a new header, ptrauth.h), with diagnostics and IRGen support. The availability of the builtins is gated on a new flag, `-fptrauth-intrinsics`. Note that this only includes the basic intrinsics, and notably excludes `ptrauth_sign_constant`, `ptrauth_type_discriminator`, and `ptrauth_string_discriminator`, which need extra logic to be fully supported. This also introduces clang/docs/PointerAuthentication.rst, which describes the ptrauth model in general, in addition to these builtins. Co-Authored-By: Akira Hatanaka Co-Authored-By: John McCall --- clang/docs/LanguageExtensions.rst | 5 + clang/docs/PointerAuthentication.rst | 265 ++ clang/include/clang/Basic/Builtins.def| 8 + clang/include/clang/Basic/DiagnosticGroups.td | 1 + .../clang/Basic/DiagnosticSemaKinds.td| 16 ++ clang/include/clang/Basic/Features.def| 1 + clang/include/clang/Basic/LangOptions.def | 2 + clang/include/clang/Basic/TargetInfo.h| 6 + clang/include/clang/Driver/Options.td | 8 + clang/include/clang/Sema/Sema.h | 2 + clang/lib/Basic/TargetInfo.cpp| 4 + clang/lib/Basic/Targets/AArch64.cpp | 6 + clang/lib/Basic/Targets/AArch64.h | 2 + clang/lib/CodeGen/CGBuiltin.cpp | 67 + clang/lib/Driver/ToolChains/Clang.cpp | 5 + clang/lib/Frontend/CompilerInvocation.cpp | 14 + clang/lib/Headers/CMakeLists.txt | 1 + clang/lib/Headers/module.modulemap| 5 + clang/lib/Headers/ptrauth.h | 167 +++ clang/lib/Sema/SemaChecking.cpp | 182 clang/test/CodeGen/ptrauth-intrinsics.c | 73 + clang/test/Preprocessor/ptrauth_feature.c | 10 + clang/test/Sema/ptrauth-intrinsics-macro.c| 34 +++ clang/test/Sema/ptrauth.c | 126 + llvm/docs/PointerAuth.md | 3 + 25 files changed, 1013 insertions(+) create mode 100644 clang/docs/PointerAuthentication.rst create mode 100644 clang/lib/Headers/ptrauth.h create mode 100644 clang/test/CodeGen/ptrauth-intrinsics.c create mode 100644 clang/test/Preprocessor/ptrauth_feature.c create mode 100644 clang/test/Sema/ptrauth-intrinsics-macro.c create mode 100644 clang/test/Sema/ptrauth.c diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 23a7f4f5d5b926..00657e6c9bfe11 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + PointerAuthentication MatrixTypes Introduction @@ -4206,6 +4207,10 @@ reordering of memory accesses and side effect instructions. Other instructions like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. +Pointer Authentication +^^ +See :doc:`PointerAuthentication`. + X86/X86-64 Language Extensions -- diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst new file mode 100644 index 00..96bcf2cd5fc824 --- /dev/null +++ b/clang/docs/PointerAuthentication.rst @@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly
[llvm] [clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
asl wrote: Looks like the review stalled. Where we are here? @ahmedbougacha @ChuanqiXu9 ? https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. kbeyls wrote: I think it would be useful to better explain what "is expected to immediately halt the program". One caveat is explained in the following sentences: this is a probabilistic mitigation, so there is a small probability that the an incorrect key and discriminator may still pass authentication. A second caveat is that, depending on the implementation, the program will only halt on *first use* of the authenticated pointer, rather than immediately on authentication. The latter may be true for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. kbeyls wrote: Arm's official spelling for ARMv8.3 is Armv8.3 (or Armv8.3-A). Might as well use that instead of ARMv8.3? https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. kbeyls wrote: Nit pick: I think the last sentence "The security of pointer authentication does not rely..." might be better moved to a different place rather than "basic concepts". Maybe there is a section about security features/aspects later in this document where this sentence would fit better? https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. kbeyls wrote: I think I'd drop the words "it was presumptively signed with". Maybe instead, I'd say "produces a raw
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. kbeyls wrote: I'm wondering if this would be a good place to state that over the years, minor variants of the PAuth architecture have been added to the AArch64 architecture. The most relevant ones for compiler implementers are probably FEAT_PAuth, FEAT_FPAC and FEAT_FPACCOMBINE? https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. kbeyls wrote: I'm wondering if the word "abstract" is needed in "abstract signing key". Does this document also talk about "concrete signing key"s? If not, dropping the word "abstract" might help readers to process this text more easily, as it triggers fewer questions in the reader's mind that remain unanswered in this paragraph. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. kbeyls wrote: Maybe spell this "Armv8.3"? I guess that with a couple of years having gone by since this was written, maybe it makes sense to drop the sentence "It is implemented on several shipping processors, including "? https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. kbeyls wrote: I *think* that for documentation, we also tend to stick to maximum 80-char line length. Might be worthwhile to reformat before landing if that is indeed the case? https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -4869,6 +4869,73 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__iso_volatile_store64: return RValue::get(EmitISOVolatileStore(*this, E)); + case Builtin::BI__builtin_ptrauth_auth: + case Builtin::BI__builtin_ptrauth_auth_and_resign: + case Builtin::BI__builtin_ptrauth_blend_discriminator: + case Builtin::BI__builtin_ptrauth_sign_generic_data: + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: + case Builtin::BI__builtin_ptrauth_strip: { +// Emit the arguments. +SmallVector args; +for (auto argExpr : E->arguments()) + args.push_back(EmitScalarExpr(argExpr)); + +// Cast the value to intptr_t, saving its original type. +llvm::Type *origValueType = args[0]->getType(); +if (origValueType->isPointerTy()) + args[0] = Builder.CreatePtrToInt(args[0], IntPtrTy); + +switch (BuiltinID) { + case Builtin::BI__builtin_ptrauth_auth_and_resign: +if (args[4]->getType()->isPointerTy()) + args[4] = Builder.CreatePtrToInt(args[4], IntPtrTy); +LLVM_FALLTHROUGH; + + case Builtin::BI__builtin_ptrauth_auth: + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: +if (args[2]->getType()->isPointerTy()) + args[2] = Builder.CreatePtrToInt(args[2], IntPtrTy); +break; + + case Builtin::BI__builtin_ptrauth_sign_generic_data: +if (args[1]->getType()->isPointerTy()) + args[1] = Builder.CreatePtrToInt(args[1], IntPtrTy); +break; + + case Builtin::BI__builtin_ptrauth_blend_discriminator: + case Builtin::BI__builtin_ptrauth_strip: +break; +} + +// Call the intrinsic. +auto intrinsicID = [&]() -> unsigned { + switch (BuiltinID) { + case Builtin::BI__builtin_ptrauth_auth: +return llvm::Intrinsic::ptrauth_auth; + case Builtin::BI__builtin_ptrauth_auth_and_resign: +return llvm::Intrinsic::ptrauth_resign; + case Builtin::BI__builtin_ptrauth_blend_discriminator: +return llvm::Intrinsic::ptrauth_blend; + case Builtin::BI__builtin_ptrauth_sign_generic_data: +return llvm::Intrinsic::ptrauth_sign_generic; + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: +return llvm::Intrinsic::ptrauth_sign; + case Builtin::BI__builtin_ptrauth_strip: +return llvm::Intrinsic::ptrauth_strip; + } + llvm_unreachable("bad ptrauth intrinsic"); +}(); +auto intrinsic = CGM.getIntrinsic(intrinsicID); +llvm::Value *result = EmitRuntimeCall(intrinsic, args); + +if (BuiltinID != Builtin::BI__builtin_ptrauth_sign_generic_data && +BuiltinID != Builtin::BI__builtin_ptrauth_blend_discriminator && +origValueType->isPointerTy()) { + result = Builder.CreateIntToPtr(result, origValueType); +} +return RValue::get(result); + } + atrosinenko wrote: Sorry for unclear wording, it should be: some existing code has inconsistent capitalization, such as the _implementation_ of [`EmitRuntimeCall` function](https://github.com/llvm/llvm-project/blob/33f6161d9eaaa7c5a01ee8e50dec440d3052d34a/clang/lib/CodeGen/CGCall.cpp#L4749) (it has arguments and local variables with names starting with lower case letter), but at least this particular function seems to have [properly-named local variables](https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly), so it is worth fixing this patch accordingly. My comment was not about method names but about local variable names, such as ```cpp auto intrinsic = CGM.getIntrinsic(intrinsicID); llvm::Value *result = EmitRuntimeCall(intrinsic, args); ``` https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/rjmccall edited https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,167 @@ +/*=== ptrauth.h - Pointer authentication ---=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===---=== + */ + +#ifndef __PTRAUTH_H +#define __PTRAUTH_H + +typedef enum { + ptrauth_key_asia = 0, + ptrauth_key_asib = 1, + ptrauth_key_asda = 2, + ptrauth_key_asdb = 3, + + /* A process-independent key which can be used to sign code pointers. + Signing and authenticating with this key is a no-op in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_independent_code = ptrauth_key_asia, + + /* A process-specific key which can be used to sign code pointers. + Signing and authenticating with this key is enforced even in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_dependent_code = ptrauth_key_asib, + + /* A process-independent key which can be used to sign data pointers. + Signing and authenticating with this key is a no-op in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_independent_data = ptrauth_key_asda, + + /* A process-specific key which can be used to sign data pointers. + Signing and authenticating with this key is a no-op in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_dependent_data = ptrauth_key_asdb, rjmccall wrote: I initially named and documented these expecting that these would be general semantic categories. As time has gone on, we've really moved away from that — they're at best platform-specific, and some of them are already out-dated (arm64e doesn't really have any "process independent" keys). https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/rjmccall edited https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -4869,6 +4869,73 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__iso_volatile_store64: return RValue::get(EmitISOVolatileStore(*this, E)); + case Builtin::BI__builtin_ptrauth_auth: + case Builtin::BI__builtin_ptrauth_auth_and_resign: + case Builtin::BI__builtin_ptrauth_blend_discriminator: + case Builtin::BI__builtin_ptrauth_sign_generic_data: + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: + case Builtin::BI__builtin_ptrauth_strip: { +// Emit the arguments. +SmallVector args; +for (auto argExpr : E->arguments()) + args.push_back(EmitScalarExpr(argExpr)); + +// Cast the value to intptr_t, saving its original type. +llvm::Type *origValueType = args[0]->getType(); +if (origValueType->isPointerTy()) + args[0] = Builder.CreatePtrToInt(args[0], IntPtrTy); + +switch (BuiltinID) { + case Builtin::BI__builtin_ptrauth_auth_and_resign: +if (args[4]->getType()->isPointerTy()) + args[4] = Builder.CreatePtrToInt(args[4], IntPtrTy); +LLVM_FALLTHROUGH; + + case Builtin::BI__builtin_ptrauth_auth: + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: +if (args[2]->getType()->isPointerTy()) + args[2] = Builder.CreatePtrToInt(args[2], IntPtrTy); +break; + + case Builtin::BI__builtin_ptrauth_sign_generic_data: +if (args[1]->getType()->isPointerTy()) + args[1] = Builder.CreatePtrToInt(args[1], IntPtrTy); +break; + + case Builtin::BI__builtin_ptrauth_blend_discriminator: + case Builtin::BI__builtin_ptrauth_strip: +break; +} + +// Call the intrinsic. +auto intrinsicID = [&]() -> unsigned { + switch (BuiltinID) { + case Builtin::BI__builtin_ptrauth_auth: +return llvm::Intrinsic::ptrauth_auth; + case Builtin::BI__builtin_ptrauth_auth_and_resign: +return llvm::Intrinsic::ptrauth_resign; + case Builtin::BI__builtin_ptrauth_blend_discriminator: +return llvm::Intrinsic::ptrauth_blend; + case Builtin::BI__builtin_ptrauth_sign_generic_data: +return llvm::Intrinsic::ptrauth_sign_generic; + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: +return llvm::Intrinsic::ptrauth_sign; + case Builtin::BI__builtin_ptrauth_strip: +return llvm::Intrinsic::ptrauth_strip; + } + llvm_unreachable("bad ptrauth intrinsic"); +}(); +auto intrinsic = CGM.getIntrinsic(intrinsicID); +llvm::Value *result = EmitRuntimeCall(intrinsic, args); + +if (BuiltinID != Builtin::BI__builtin_ptrauth_sign_generic_data && +BuiltinID != Builtin::BI__builtin_ptrauth_blend_discriminator && +origValueType->isPointerTy()) { + result = Builder.CreateIntToPtr(result, origValueType); +} +return RValue::get(result); + } + rjmccall wrote: The codebase is generally inconsistent about this, but we've been moving towards lowercasing leading letters of methods in new code. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -1908,6 +1908,176 @@ static bool SemaOpenCLBuiltinToAddr(Sema , unsigned BuiltinID, return false; } +namespace { + enum PointerAuthOpKind { +PAO_Strip, PAO_Sign, PAO_Auth, PAO_SignGeneric, PAO_Discriminator, +PAO_BlendPointer, PAO_BlendInteger + }; +} + +static bool checkPointerAuthEnabled(Sema , Expr *E) { + if (S.getLangOpts().PointerAuthIntrinsics) +return false; + + S.Diag(E->getExprLoc(), diag::err_ptrauth_disabled) << E->getSourceRange(); + return true; +} + +static bool checkPointerAuthKey(Sema , Expr *) { + // Convert it to type 'int'. + if (convertArgumentToType(S, Arg, S.Context.IntTy)) +return true; + + // Value-dependent expressions are okay; wait for template instantiation. + if (Arg->isValueDependent()) +return false; + + unsigned KeyValue; + return S.checkConstantPointerAuthKey(Arg, KeyValue); +} + +bool Sema::checkConstantPointerAuthKey(Expr *Arg, unsigned ) { + // Attempt to constant-evaluate the expression. + std::optional KeyValue = Arg->getIntegerConstantExpr(Context); + if (!KeyValue) { +Diag(Arg->getExprLoc(), diag::err_expr_not_ice) << 0 + << Arg->getSourceRange(); +return true; + } + + // Ask the target to validate the key parameter. + if (!Context.getTargetInfo().validatePointerAuthKey(*KeyValue)) { +llvm::SmallString<32> Value; { + llvm::raw_svector_ostream Str(Value); + Str << *KeyValue; +} + +Diag(Arg->getExprLoc(), diag::err_ptrauth_invalid_key) + << Value << Arg->getSourceRange(); +return true; + } + + Result = KeyValue->getZExtValue(); + return false; +} + +static bool checkPointerAuthValue(Sema , Expr *, + PointerAuthOpKind OpKind) { + if (Arg->hasPlaceholderType()) { +ExprResult R = S.CheckPlaceholderExpr(Arg); +if (R.isInvalid()) return true; +Arg = R.get(); + } + + auto allowsPointer = [](PointerAuthOpKind OpKind) { +return OpKind != PAO_BlendInteger; + }; + auto allowsInteger = [](PointerAuthOpKind OpKind) { atrosinenko wrote: Local variable name starts with lower case. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,167 @@ +/*=== ptrauth.h - Pointer authentication ---=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===---=== + */ + +#ifndef __PTRAUTH_H +#define __PTRAUTH_H + +typedef enum { + ptrauth_key_asia = 0, + ptrauth_key_asib = 1, + ptrauth_key_asda = 2, + ptrauth_key_asdb = 3, + + /* A process-independent key which can be used to sign code pointers. + Signing and authenticating with this key is a no-op in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_independent_code = ptrauth_key_asia, + + /* A process-specific key which can be used to sign code pointers. + Signing and authenticating with this key is enforced even in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_dependent_code = ptrauth_key_asib, + + /* A process-independent key which can be used to sign data pointers. + Signing and authenticating with this key is a no-op in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_independent_data = ptrauth_key_asda, + + /* A process-specific key which can be used to sign data pointers. + Signing and authenticating with this key is a no-op in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_dependent_data = ptrauth_key_asdb, atrosinenko wrote: I wonder if each supported platform would have keys with all these properties. Is it mandated by ARM or is it arm64e-specific? https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,167 @@ +/*=== ptrauth.h - Pointer authentication ---=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===---=== + */ + +#ifndef __PTRAUTH_H +#define __PTRAUTH_H + +typedef enum { + ptrauth_key_asia = 0, + ptrauth_key_asib = 1, + ptrauth_key_asda = 2, + ptrauth_key_asdb = 3, + + /* A process-independent key which can be used to sign code pointers. + Signing and authenticating with this key is a no-op in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_independent_code = ptrauth_key_asia, + + /* A process-specific key which can be used to sign code pointers. + Signing and authenticating with this key is enforced even in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_dependent_code = ptrauth_key_asib, + + /* A process-independent key which can be used to sign data pointers. + Signing and authenticating with this key is a no-op in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_independent_data = ptrauth_key_asda, + + /* A process-specific key which can be used to sign data pointers. + Signing and authenticating with this key is a no-op in processes + which disable ABI pointer authentication. */ + ptrauth_key_process_dependent_data = ptrauth_key_asdb, + +} ptrauth_key; + +/* An integer type of the appropriate size for a discriminator argument. */ +typedef __UINTPTR_TYPE__ ptrauth_extra_data_t; + +/* An integer type of the appropriate size for a generic signature. */ +typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; + +/* A signed pointer value embeds the original pointer together with + a signature that attests to the validity of that pointer. Because + this signature must use only "spare" bits of the pointer, a + signature's validity is probabilistic in practice: it is unlikely + but still plausible that an invalidly-derived signature will + somehow equal the correct signature and therefore successfully + authenticate. Nonetheless, this scheme provides a strong degree + of protection against certain kinds of attacks. */ + +/* Authenticating a pointer that was not signed with the given key + and extra-data value will (likely) fail by trapping. */ + +#if __has_feature(ptrauth_intrinsics) + +/* Strip the signature from a value without authenticating it. + + If the value is a function pointer, the result will not be a + legal function pointer because of the missing signature, and + attempting to call it will result in an authentication failure. + + The value must be an expression of pointer type. + The key must be a constant expression of type ptrauth_key. + The result will have the same type as the original value. */ +#define ptrauth_strip(__value, __key) \ + __builtin_ptrauth_strip(__value, __key) + +/* Blend a constant discriminator into the given pointer-like value + to form a new discriminator. Not all bits of the inputs are + guaranteed to contribute to the result. + + On arm64e, the integer must fall within the range of a uint16_t; + other bits may be ignored. + + The first argument must be an expression of pointer type. + The second argument must be an expression of integer type. + The result will have type uintptr_t. */ +#define ptrauth_blend_discriminator(__pointer, __integer) \ + __builtin_ptrauth_blend_discriminator(__pointer, __integer) + +/* Add a signature to the given pointer value using a specific key, + using the given extra data as a salt to the signing process. + + This operation does not authenticate the original value and is + therefore potentially insecure if an attacker could possibly + control that value. + + The value must be an expression of pointer type. + The key must be a constant expression of type ptrauth_key. + The extra data must be an expression of pointer or integer type; + if an integer, it will be coerced to ptrauth_extra_data_t. + The result will have the same type as the original value. */ +#define ptrauth_sign_unauthenticated(__value, __key, __data) \ + __builtin_ptrauth_sign_unauthenticated(__value, __key, __data) + +/* Authenticate a pointer using one scheme and resign it using another. + + If the result is subsequently authenticated using the new scheme, that + authentication is guaranteed to fail if and only if the initial + authentication failed. + + The value must be an expression of pointer type. + The key must be a constant expression of type ptrauth_key. + The extra data must be an expression of pointer or integer type; + if an integer, it will be coerced to ptrauth_extra_data_t. + The result will have the same type as the original value. + + This
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -4869,6 +4869,73 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, case Builtin::BI__iso_volatile_store64: return RValue::get(EmitISOVolatileStore(*this, E)); + case Builtin::BI__builtin_ptrauth_auth: + case Builtin::BI__builtin_ptrauth_auth_and_resign: + case Builtin::BI__builtin_ptrauth_blend_discriminator: + case Builtin::BI__builtin_ptrauth_sign_generic_data: + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: + case Builtin::BI__builtin_ptrauth_strip: { +// Emit the arguments. +SmallVector args; +for (auto argExpr : E->arguments()) + args.push_back(EmitScalarExpr(argExpr)); + +// Cast the value to intptr_t, saving its original type. +llvm::Type *origValueType = args[0]->getType(); +if (origValueType->isPointerTy()) + args[0] = Builder.CreatePtrToInt(args[0], IntPtrTy); + +switch (BuiltinID) { + case Builtin::BI__builtin_ptrauth_auth_and_resign: +if (args[4]->getType()->isPointerTy()) + args[4] = Builder.CreatePtrToInt(args[4], IntPtrTy); +LLVM_FALLTHROUGH; + + case Builtin::BI__builtin_ptrauth_auth: + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: +if (args[2]->getType()->isPointerTy()) + args[2] = Builder.CreatePtrToInt(args[2], IntPtrTy); +break; + + case Builtin::BI__builtin_ptrauth_sign_generic_data: +if (args[1]->getType()->isPointerTy()) + args[1] = Builder.CreatePtrToInt(args[1], IntPtrTy); +break; + + case Builtin::BI__builtin_ptrauth_blend_discriminator: + case Builtin::BI__builtin_ptrauth_strip: +break; +} + +// Call the intrinsic. +auto intrinsicID = [&]() -> unsigned { + switch (BuiltinID) { + case Builtin::BI__builtin_ptrauth_auth: +return llvm::Intrinsic::ptrauth_auth; + case Builtin::BI__builtin_ptrauth_auth_and_resign: +return llvm::Intrinsic::ptrauth_resign; + case Builtin::BI__builtin_ptrauth_blend_discriminator: +return llvm::Intrinsic::ptrauth_blend; + case Builtin::BI__builtin_ptrauth_sign_generic_data: +return llvm::Intrinsic::ptrauth_sign_generic; + case Builtin::BI__builtin_ptrauth_sign_unauthenticated: +return llvm::Intrinsic::ptrauth_sign; + case Builtin::BI__builtin_ptrauth_strip: +return llvm::Intrinsic::ptrauth_strip; + } + llvm_unreachable("bad ptrauth intrinsic"); +}(); +auto intrinsic = CGM.getIntrinsic(intrinsicID); +llvm::Value *result = EmitRuntimeCall(intrinsic, args); + +if (BuiltinID != Builtin::BI__builtin_ptrauth_sign_generic_data && +BuiltinID != Builtin::BI__builtin_ptrauth_blend_discriminator && +origValueType->isPointerTy()) { + result = Builder.CreateIntToPtr(result, origValueType); +} +return RValue::get(result); + } + atrosinenko wrote: This function seems to use the traditional code style of starting local variable names with a capital letter (unlike `EmitRuntimeCall` from CGCall.cpp, for example). https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -6973,6 +6973,11 @@ void Clang::ConstructJob(Compilation , const JobAction , // -fno-common is the default, set -fcommon only when that flag is set. Args.addOptInFlag(CmdArgs, options::OPT_fcommon, options::OPT_fno_common); + if (Args.hasFlag(options::OPT_fptrauth_intrinsics, + options::OPT_fno_ptrauth_intrinsics, false)) +CmdArgs.push_back("-fptrauth-intrinsics"); + + atrosinenko wrote: Extra newline. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **PAuth** (sometimes referred to as **PAC**, for Pointer Authentication Codes) is an AArch64 architecture extension that provides hardware support for pointer authentication. + +- **ARMv8.3** is an AArch64 architecture revision that makes PAuth mandatory. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI (not yet fully stable) for implementing pointer authentication using PAuth on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It will eventually present a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3 PAuth) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. atrosinenko wrote: It may be more readable to avoid "can dramatically lower the execution speed" substring when mentioning "lowering execution speed and size costs" :) https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
atrosinenko wrote: Meanwhile, isn't the C++ standard use the term "safely-derived pointer", too? https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
atrosinenko wrote: As already mentioned by @DavidSpickett , part of `PointerAuthentication.rst` file disappeared, thus some links are dangling now. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
DavidSpickett wrote: Maybe I just need to learn how to use Github, but did half the document disappear? I see a reference to the attacks section `See the section on `Attacks on pointer authentication`_ for more information.` but the section is gone from the diff even in a private window. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/DavidSpickett resolved https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/DavidSpickett resolved https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/DavidSpickett resolved https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. DavidSpickett wrote: Well let me put my perspective and you can take or leave it, it's not actually that important overall :) If I read "a conforming implementation is expected to", I could substitute that with "must do". In fact, I'd probably just write it the second way to be 100% clear. Also I'm used to dealing with PAuth without supporting ABIs and at an architecture level no exception is raised, so I'm biased. Any real user will likely be seeing this via an ABI that does raise exceptions. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/DavidSpickett resolved https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. DavidSpickett wrote: Agreed. PAuth in a generic context looks too much like a typo or abbreviation for the generic technique, especially in this document which points out that distinction. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -303,6 +303,10 @@ bool Module::directlyUses(const Module *Requested) { if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") return true; + // Anyone is allowed to use our builtin ptrauth.h and its accompanying module. + if (!Requested->Parent && Requested->Name == "ptrauth") ChuanqiXu9 wrote: On the one hand, I don't think it is necessary to support modules in the first step. On the other hand, we can try to get the same semantics by adding new mechanism to modules. e.g., we can declare some modules are always directly usable in the module map. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -303,6 +303,10 @@ bool Module::directlyUses(const Module *Requested) { if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") return true; + // Anyone is allowed to use our builtin ptrauth.h and its accompanying module. + if (!Requested->Parent && Requested->Name == "ptrauth") ahmedbougacha wrote: It’s needed in this patch because this patch introduces the `ptrauth.h` header file, which wouldn’t be usable from modules without this change. If you have an alternative fix I’m open to suggestions. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha edited https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -303,6 +303,10 @@ bool Module::directlyUses(const Module *Requested) { if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") return true; + // Anyone is allowed to use our builtin ptrauth.h and its accompanying module. + if (!Requested->Parent && Requested->Name == "ptrauth") ChuanqiXu9 wrote: But this is still dirty and not good. We should try to find a better way to implement the semantics. Also I am wondering if this change is really necessary to the current patch. I mean, what if we drop the modules related change in the current patch and add it later in another patch? https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha updated https://github.com/llvm/llvm-project/pull/65996: >From fccf0643bd7812301819f5c7fce30d81c6e86a80 Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Wed, 16 Aug 2023 09:17:12 -0700 Subject: [PATCH] [AArch64][PAC] Support and document ptrauth builtins and -fptrauth-intrinsics. This defines the basic set of pointer authentication clang builtins (provided in a new header, ptrauth.h), with diagnostics and IRGen support. The availability of the builtins is gated on a new flag, `-fptrauth-intrinsics`. Note that this only includes the basic intrinsics, and notably excludes `ptrauth_sign_constant`, `ptrauth_type_discriminator`, and `ptrauth_string_discriminator`, which need extra logic to be fully supported. This also introduces clang/docs/PointerAuthentication.rst, which describes the ptrauth model in general, in addition to these builtins. Co-Authored-By: Akira Hatanaka Co-Authored-By: John McCall --- clang/docs/LanguageExtensions.rst | 5 + clang/docs/PointerAuthentication.rst | 265 ++ clang/include/clang/Basic/Builtins.def| 8 + clang/include/clang/Basic/DiagnosticGroups.td | 1 + .../clang/Basic/DiagnosticSemaKinds.td| 16 ++ clang/include/clang/Basic/Features.def| 1 + clang/include/clang/Basic/LangOptions.def | 2 + clang/include/clang/Basic/TargetInfo.h| 6 + clang/include/clang/Driver/Options.td | 8 + clang/include/clang/Sema/Sema.h | 2 + clang/lib/Basic/Module.cpp| 4 + clang/lib/Basic/TargetInfo.cpp| 4 + clang/lib/Basic/Targets/AArch64.cpp | 6 + clang/lib/Basic/Targets/AArch64.h | 2 + clang/lib/CodeGen/CGBuiltin.cpp | 67 + clang/lib/Driver/ToolChains/Clang.cpp | 5 + clang/lib/Frontend/CompilerInvocation.cpp | 13 + clang/lib/Headers/CMakeLists.txt | 1 + clang/lib/Headers/module.modulemap| 5 + clang/lib/Headers/ptrauth.h | 167 +++ clang/lib/Sema/SemaChecking.cpp | 182 clang/test/CodeGen/ptrauth-intrinsics.c | 73 + .../module.modulemap | 8 + .../ptrauth-include-from-darwin/ptrauth.h | 1 + .../ptrauth-include-from-darwin/stddef.h | 1 + .../Modules/ptrauth-include-from-darwin.m | 6 + clang/test/Preprocessor/ptrauth_feature.c | 10 + clang/test/Sema/ptrauth-intrinsics-macro.c| 34 +++ clang/test/Sema/ptrauth.c | 126 + llvm/docs/PointerAuth.md | 3 + 30 files changed, 1032 insertions(+) create mode 100644 clang/docs/PointerAuthentication.rst create mode 100644 clang/lib/Headers/ptrauth.h create mode 100644 clang/test/CodeGen/ptrauth-intrinsics.c create mode 100644 clang/test/Modules/Inputs/ptrauth-include-from-darwin/module.modulemap create mode 100644 clang/test/Modules/Inputs/ptrauth-include-from-darwin/ptrauth.h create mode 100644 clang/test/Modules/Inputs/ptrauth-include-from-darwin/stddef.h create mode 100644 clang/test/Modules/ptrauth-include-from-darwin.m create mode 100644 clang/test/Preprocessor/ptrauth_feature.c create mode 100644 clang/test/Sema/ptrauth-intrinsics-macro.c create mode 100644 clang/test/Sema/ptrauth.c diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 11cbdca7a268fc3..49a3934d9d082fc 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + PointerAuthentication MatrixTypes Introduction @@ -4157,6 +4158,10 @@ reordering of memory accesses and side effect instructions. Other instructions like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. +Pointer Authentication +^^ +See :doc:`PointerAuthentication`. + X86/X86-64 Language Extensions -- diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst new file mode 100644 index 000..96bcf2cd5fc824b --- /dev/null +++ b/clang/docs/PointerAuthentication.rst @@ -0,0 +1,265 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha edited https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. ahmedbougacha wrote: I read "ultimately" here as "boiled down to the important part" (so, e.g., allowing value-preserving conversions between the auth/sign); we could remove the word altogether though! As for "expected", I think that's in opposition to the next sentence, about the unexpected cases where it doesn't actually do that ;) https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -303,6 +303,10 @@ bool Module::directlyUses(const Module *Requested) { if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") return true; + // Anyone is allowed to use our builtin ptrauth.h and its accompanying module. + if (!Requested->Parent && Requested->Name == "ptrauth") ahmedbougacha wrote: Unfortunately this is needed, to match the (compiler-interface-defining) `ptrauth.h` header file we vend. (specifically this is to allow usage of `ptrauth.h` from `no_undeclared_interfaces` modules, see ed84df008f609. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. DavidSpickett wrote: "was originally produced" seems to make more sense here. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that provides hardware support for pointer authentication. It is implemented on several shipping processors, including the Apple A12 and later. + +* **arm64e** is a specific ABI for (not yet fully stable) for implementing pointer authentication on ARMv8.3 on certain Apple operating systems. + +This document serves four purposes: + +- It describes the basic ideas of pointer authentication. + +- It documents several language extensions that are useful on targets using pointer authentication. + +- It presents a theory of operation for the security mitigation, describing the basic requirements for correctness, various weaknesses in the mechanism, and ways in which programmers can strengthen its protections (including recommendations for language implementors). + +- It will eventually document the language ABIs currently used for C, C++, Objective-C, and Swift on arm64e, although these are not yet stable on any target. + +Basic Concepts +-- + +The simple address of an object or function is a **raw pointer**. A raw pointer can be **signed** to produce a **signed pointer**. A signed pointer can be then **authenticated** in order to verify that it was **validly signed** and extract the original raw pointer. These terms reflect the most likely implementation technique: computing and storing a cryptographic signature along with the pointer. The security of pointer authentication does not rely on attackers not being able to separately overwrite the signature. + +An **abstract signing key** is a name which refers to a secret key which can used to sign and authenticate pointers. The key value for a particular name is consistent throughout a process. + +A **discriminator** is an arbitrary value used to **diversify** signed pointers so that one validly-signed pointer cannot simply be copied over another. A discriminator is simply opaque data of some implementation-defined size that is included in the signature as a salt. + +Nearly all aspects of pointer authentication use just these two primary operations: + +- ``sign(raw_pointer, key, discriminator)`` produces a signed pointer given a raw pointer, an abstract signing key, and a discriminator. + +- ``auth(signed_pointer, key, discriminator)`` produces a raw pointer given a signed pointer, an abstract signing key, and a discriminator. + +``auth(sign(raw_pointer, key, discriminator), key, discriminator)`` must succeed and produce ``raw_pointer``. ``auth`` applied to a value that was ultimately produced in any other way is expected to immediately halt the program. However, it is permitted for ``auth`` to fail to detect that a signed pointer was not produced in this way, in which case it may return anything; this is what makes pointer authentication a probabilistic mitigation rather than a perfect one. + +There are two secondary operations which are required only to implement certain intrinsics in : + +- ``strip(signed_pointer, key)`` produces a raw pointer given a signed pointer and a key it was presumptively signed with. This is useful for certain kinds of tooling, such as crash backtraces; it should generally not be used in the basic language ABI except in very careful ways. + +- ``sign_generic(value)`` produces a cryptographic signature for arbitrary data, not necessarily a pointer. This is useful for efficiently verifying that non-pointer data has not been tampered with. + +Whenever any of these operations is called for, the key value must be known statically. This is
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
@@ -303,6 +303,10 @@ bool Module::directlyUses(const Module *Requested) { if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t") return true; + // Anyone is allowed to use our builtin ptrauth.h and its accompanying module. + if (!Requested->Parent && Requested->Name == "ptrauth") ChuanqiXu9 wrote: While I haven't understood the patch fully, I believe hardcoding the module name in such a style is not good. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ChuanqiXu9 edited https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ChuanqiXu9 requested changes to this pull request. https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
llvmbot wrote: @llvm/pr-subscribers-clang-modules Changes This defines the basic set of pointer authentication clang builtins (provided in a new header, ptrauth.h), with diagnostics and IRGen support. The availability of the builtins is gated on a new flag, `-fptrauth-intrinsics`. Note that this only includes the basic intrinsics, and notably excludes `ptrauth_sign_constant`, `ptrauth_type_discriminator`, and `ptrauth_string_discriminator`, which need extra logic to be fully supported. This also introduces clang/docs/PointerAuthentication.rst, which describes the ptrauth model in general, as well as these builtins. (Replaces https://reviews.llvm.org/D112941) -- Patch is 93.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/65996.diff 30 Files Affected: - (modified) clang/docs/LanguageExtensions.rst (+5) - (added) clang/docs/PointerAuthentication.rst (+548) - (modified) clang/include/clang/Basic/Builtins.def (+8) - (modified) clang/include/clang/Basic/DiagnosticGroups.td (+1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+16) - (modified) clang/include/clang/Basic/Features.def (+1) - (modified) clang/include/clang/Basic/LangOptions.def (+2) - (modified) clang/include/clang/Basic/TargetInfo.h (+6) - (modified) clang/include/clang/Driver/Options.td (+8) - (modified) clang/include/clang/Sema/Sema.h (+2) - (modified) clang/lib/Basic/Module.cpp (+4) - (modified) clang/lib/Basic/TargetInfo.cpp (+4) - (modified) clang/lib/Basic/Targets/AArch64.cpp (+6) - (modified) clang/lib/Basic/Targets/AArch64.h (+2) - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+67) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+5) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+13) - (modified) clang/lib/Headers/CMakeLists.txt (+1) - (modified) clang/lib/Headers/module.modulemap (+5) - (added) clang/lib/Headers/ptrauth.h (+167) - (modified) clang/lib/Sema/SemaChecking.cpp (+182) - (added) clang/test/CodeGen/ptrauth-intrinsics.c (+73) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/module.modulemap (+8) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/ptrauth.h (+1) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/stddef.h (+1) - (added) clang/test/Modules/ptrauth-include-from-darwin.m (+6) - (added) clang/test/Preprocessor/ptrauth_feature.c (+10) - (added) clang/test/Sema/ptrauth-intrinsics-macro.c (+34) - (added) clang/test/Sema/ptrauth.c (+126) - (modified) llvm/docs/PointerAuth.md (+3) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 11cbdca7a268fc3..49a3934d9d082fc 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + PointerAuthentication MatrixTypes Introduction @@ -4157,6 +4158,10 @@ reordering of memory accesses and side effect instructions. Other instructions like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. +Pointer Authentication +^^ +See :doc:`PointerAuthentication`. + X86/X86-64 Language Extensions -- diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst new file mode 100644 index 000..87b8f244a2e4653 --- /dev/null +++ b/clang/docs/PointerAuthentication.rst @@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
llvmbot wrote: @llvm/pr-subscribers-backend-aarch64 Changes This defines the basic set of pointer authentication clang builtins (provided in a new header, ptrauth.h), with diagnostics and IRGen support. The availability of the builtins is gated on a new flag, `-fptrauth-intrinsics`. Note that this only includes the basic intrinsics, and notably excludes `ptrauth_sign_constant`, `ptrauth_type_discriminator`, and `ptrauth_string_discriminator`, which need extra logic to be fully supported. This also introduces clang/docs/PointerAuthentication.rst, which describes the ptrauth model in general, as well as these builtins. (Replaces https://reviews.llvm.org/D112941) -- Patch is 93.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/65996.diff 30 Files Affected: - (modified) clang/docs/LanguageExtensions.rst (+5) - (added) clang/docs/PointerAuthentication.rst (+548) - (modified) clang/include/clang/Basic/Builtins.def (+8) - (modified) clang/include/clang/Basic/DiagnosticGroups.td (+1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+16) - (modified) clang/include/clang/Basic/Features.def (+1) - (modified) clang/include/clang/Basic/LangOptions.def (+2) - (modified) clang/include/clang/Basic/TargetInfo.h (+6) - (modified) clang/include/clang/Driver/Options.td (+8) - (modified) clang/include/clang/Sema/Sema.h (+2) - (modified) clang/lib/Basic/Module.cpp (+4) - (modified) clang/lib/Basic/TargetInfo.cpp (+4) - (modified) clang/lib/Basic/Targets/AArch64.cpp (+6) - (modified) clang/lib/Basic/Targets/AArch64.h (+2) - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+67) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+5) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+13) - (modified) clang/lib/Headers/CMakeLists.txt (+1) - (modified) clang/lib/Headers/module.modulemap (+5) - (added) clang/lib/Headers/ptrauth.h (+167) - (modified) clang/lib/Sema/SemaChecking.cpp (+182) - (added) clang/test/CodeGen/ptrauth-intrinsics.c (+73) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/module.modulemap (+8) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/ptrauth.h (+1) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/stddef.h (+1) - (added) clang/test/Modules/ptrauth-include-from-darwin.m (+6) - (added) clang/test/Preprocessor/ptrauth_feature.c (+10) - (added) clang/test/Sema/ptrauth-intrinsics-macro.c (+34) - (added) clang/test/Sema/ptrauth.c (+126) - (modified) llvm/docs/PointerAuth.md (+3) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 11cbdca7a268fc3..49a3934d9d082fc 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + PointerAuthentication MatrixTypes Introduction @@ -4157,6 +4158,10 @@ reordering of memory accesses and side effect instructions. Other instructions like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. +Pointer Authentication +^^ +See :doc:`PointerAuthentication`. + X86/X86-64 Language Extensions -- diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst new file mode 100644 index 000..87b8f244a2e4653 --- /dev/null +++ b/clang/docs/PointerAuthentication.rst @@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
llvmbot wrote: @llvm/pr-subscribers-backend-x86 Changes This defines the basic set of pointer authentication clang builtins (provided in a new header, ptrauth.h), with diagnostics and IRGen support. The availability of the builtins is gated on a new flag, `-fptrauth-intrinsics`. Note that this only includes the basic intrinsics, and notably excludes `ptrauth_sign_constant`, `ptrauth_type_discriminator`, and `ptrauth_string_discriminator`, which need extra logic to be fully supported. This also introduces clang/docs/PointerAuthentication.rst, which describes the ptrauth model in general, as well as these builtins. (Replaces https://reviews.llvm.org/D112941) -- Patch is 93.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/65996.diff 30 Files Affected: - (modified) clang/docs/LanguageExtensions.rst (+5) - (added) clang/docs/PointerAuthentication.rst (+548) - (modified) clang/include/clang/Basic/Builtins.def (+8) - (modified) clang/include/clang/Basic/DiagnosticGroups.td (+1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+16) - (modified) clang/include/clang/Basic/Features.def (+1) - (modified) clang/include/clang/Basic/LangOptions.def (+2) - (modified) clang/include/clang/Basic/TargetInfo.h (+6) - (modified) clang/include/clang/Driver/Options.td (+8) - (modified) clang/include/clang/Sema/Sema.h (+2) - (modified) clang/lib/Basic/Module.cpp (+4) - (modified) clang/lib/Basic/TargetInfo.cpp (+4) - (modified) clang/lib/Basic/Targets/AArch64.cpp (+6) - (modified) clang/lib/Basic/Targets/AArch64.h (+2) - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+67) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+5) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+13) - (modified) clang/lib/Headers/CMakeLists.txt (+1) - (modified) clang/lib/Headers/module.modulemap (+5) - (added) clang/lib/Headers/ptrauth.h (+167) - (modified) clang/lib/Sema/SemaChecking.cpp (+182) - (added) clang/test/CodeGen/ptrauth-intrinsics.c (+73) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/module.modulemap (+8) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/ptrauth.h (+1) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/stddef.h (+1) - (added) clang/test/Modules/ptrauth-include-from-darwin.m (+6) - (added) clang/test/Preprocessor/ptrauth_feature.c (+10) - (added) clang/test/Sema/ptrauth-intrinsics-macro.c (+34) - (added) clang/test/Sema/ptrauth.c (+126) - (modified) llvm/docs/PointerAuth.md (+3) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 11cbdca7a268fc3..49a3934d9d082fc 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + PointerAuthentication MatrixTypes Introduction @@ -4157,6 +4158,10 @@ reordering of memory accesses and side effect instructions. Other instructions like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. +Pointer Authentication +^^ +See :doc:`PointerAuthentication`. + X86/X86-64 Language Extensions -- diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst new file mode 100644 index 000..87b8f244a2e4653 --- /dev/null +++ b/clang/docs/PointerAuthentication.rst @@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
llvmbot wrote: @llvm/pr-subscribers-clang Changes This defines the basic set of pointer authentication clang builtins (provided in a new header, ptrauth.h), with diagnostics and IRGen support. The availability of the builtins is gated on a new flag, `-fptrauth-intrinsics`. Note that this only includes the basic intrinsics, and notably excludes `ptrauth_sign_constant`, `ptrauth_type_discriminator`, and `ptrauth_string_discriminator`, which need extra logic to be fully supported. This also introduces clang/docs/PointerAuthentication.rst, which describes the ptrauth model in general, as well as these builtins. (Replaces https://reviews.llvm.org/D112941) -- Patch is 93.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/65996.diff 30 Files Affected: - (modified) clang/docs/LanguageExtensions.rst (+5) - (added) clang/docs/PointerAuthentication.rst (+548) - (modified) clang/include/clang/Basic/Builtins.def (+8) - (modified) clang/include/clang/Basic/DiagnosticGroups.td (+1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+16) - (modified) clang/include/clang/Basic/Features.def (+1) - (modified) clang/include/clang/Basic/LangOptions.def (+2) - (modified) clang/include/clang/Basic/TargetInfo.h (+6) - (modified) clang/include/clang/Driver/Options.td (+8) - (modified) clang/include/clang/Sema/Sema.h (+2) - (modified) clang/lib/Basic/Module.cpp (+4) - (modified) clang/lib/Basic/TargetInfo.cpp (+4) - (modified) clang/lib/Basic/Targets/AArch64.cpp (+6) - (modified) clang/lib/Basic/Targets/AArch64.h (+2) - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+67) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+5) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+13) - (modified) clang/lib/Headers/CMakeLists.txt (+1) - (modified) clang/lib/Headers/module.modulemap (+5) - (added) clang/lib/Headers/ptrauth.h (+167) - (modified) clang/lib/Sema/SemaChecking.cpp (+182) - (added) clang/test/CodeGen/ptrauth-intrinsics.c (+73) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/module.modulemap (+8) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/ptrauth.h (+1) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/stddef.h (+1) - (added) clang/test/Modules/ptrauth-include-from-darwin.m (+6) - (added) clang/test/Preprocessor/ptrauth_feature.c (+10) - (added) clang/test/Sema/ptrauth-intrinsics-macro.c (+34) - (added) clang/test/Sema/ptrauth.c (+126) - (modified) llvm/docs/PointerAuth.md (+3) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 11cbdca7a268fc3..49a3934d9d082fc 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + PointerAuthentication MatrixTypes Introduction @@ -4157,6 +4158,10 @@ reordering of memory accesses and side effect instructions. Other instructions like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. +Pointer Authentication +^^ +See :doc:`PointerAuthentication`. + X86/X86-64 Language Extensions -- diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst new file mode 100644 index 000..87b8f244a2e4653 --- /dev/null +++ b/clang/docs/PointerAuthentication.rst @@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision of that
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
llvmbot wrote: @llvm/pr-subscribers-clang-driver Changes This defines the basic set of pointer authentication clang builtins (provided in a new header, ptrauth.h), with diagnostics and IRGen support. The availability of the builtins is gated on a new flag, `-fptrauth-intrinsics`. Note that this only includes the basic intrinsics, and notably excludes `ptrauth_sign_constant`, `ptrauth_type_discriminator`, and `ptrauth_string_discriminator`, which need extra logic to be fully supported. This also introduces clang/docs/PointerAuthentication.rst, which describes the ptrauth model in general, as well as these builtins. (Replaces https://reviews.llvm.org/D112941) -- Patch is 93.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/65996.diff 30 Files Affected: - (modified) clang/docs/LanguageExtensions.rst (+5) - (added) clang/docs/PointerAuthentication.rst (+548) - (modified) clang/include/clang/Basic/Builtins.def (+8) - (modified) clang/include/clang/Basic/DiagnosticGroups.td (+1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+16) - (modified) clang/include/clang/Basic/Features.def (+1) - (modified) clang/include/clang/Basic/LangOptions.def (+2) - (modified) clang/include/clang/Basic/TargetInfo.h (+6) - (modified) clang/include/clang/Driver/Options.td (+8) - (modified) clang/include/clang/Sema/Sema.h (+2) - (modified) clang/lib/Basic/Module.cpp (+4) - (modified) clang/lib/Basic/TargetInfo.cpp (+4) - (modified) clang/lib/Basic/Targets/AArch64.cpp (+6) - (modified) clang/lib/Basic/Targets/AArch64.h (+2) - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+67) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+5) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+13) - (modified) clang/lib/Headers/CMakeLists.txt (+1) - (modified) clang/lib/Headers/module.modulemap (+5) - (added) clang/lib/Headers/ptrauth.h (+167) - (modified) clang/lib/Sema/SemaChecking.cpp (+182) - (added) clang/test/CodeGen/ptrauth-intrinsics.c (+73) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/module.modulemap (+8) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/ptrauth.h (+1) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/stddef.h (+1) - (added) clang/test/Modules/ptrauth-include-from-darwin.m (+6) - (added) clang/test/Preprocessor/ptrauth_feature.c (+10) - (added) clang/test/Sema/ptrauth-intrinsics-macro.c (+34) - (added) clang/test/Sema/ptrauth.c (+126) - (modified) llvm/docs/PointerAuth.md (+3) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 11cbdca7a268fc3..49a3934d9d082fc 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + PointerAuthentication MatrixTypes Introduction @@ -4157,6 +4158,10 @@ reordering of memory accesses and side effect instructions. Other instructions like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. +Pointer Authentication +^^ +See :doc:`PointerAuthentication`. + X86/X86-64 Language Extensions -- diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst new file mode 100644 index 000..87b8f244a2e4653 --- /dev/null +++ b/clang/docs/PointerAuthentication.rst @@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
llvmbot wrote: @llvm/pr-subscribers-clang-codegen Changes This defines the basic set of pointer authentication clang builtins (provided in a new header, ptrauth.h), with diagnostics and IRGen support. The availability of the builtins is gated on a new flag, `-fptrauth-intrinsics`. Note that this only includes the basic intrinsics, and notably excludes `ptrauth_sign_constant`, `ptrauth_type_discriminator`, and `ptrauth_string_discriminator`, which need extra logic to be fully supported. This also introduces clang/docs/PointerAuthentication.rst, which describes the ptrauth model in general, as well as these builtins. (Replaces https://reviews.llvm.org/D112941) -- Patch is 93.58 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/65996.diff 30 Files Affected: - (modified) clang/docs/LanguageExtensions.rst (+5) - (added) clang/docs/PointerAuthentication.rst (+548) - (modified) clang/include/clang/Basic/Builtins.def (+8) - (modified) clang/include/clang/Basic/DiagnosticGroups.td (+1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+16) - (modified) clang/include/clang/Basic/Features.def (+1) - (modified) clang/include/clang/Basic/LangOptions.def (+2) - (modified) clang/include/clang/Basic/TargetInfo.h (+6) - (modified) clang/include/clang/Driver/Options.td (+8) - (modified) clang/include/clang/Sema/Sema.h (+2) - (modified) clang/lib/Basic/Module.cpp (+4) - (modified) clang/lib/Basic/TargetInfo.cpp (+4) - (modified) clang/lib/Basic/Targets/AArch64.cpp (+6) - (modified) clang/lib/Basic/Targets/AArch64.h (+2) - (modified) clang/lib/CodeGen/CGBuiltin.cpp (+67) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+5) - (modified) clang/lib/Frontend/CompilerInvocation.cpp (+13) - (modified) clang/lib/Headers/CMakeLists.txt (+1) - (modified) clang/lib/Headers/module.modulemap (+5) - (added) clang/lib/Headers/ptrauth.h (+167) - (modified) clang/lib/Sema/SemaChecking.cpp (+182) - (added) clang/test/CodeGen/ptrauth-intrinsics.c (+73) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/module.modulemap (+8) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/ptrauth.h (+1) - (added) clang/test/Modules/Inputs/ptrauth-include-from-darwin/stddef.h (+1) - (added) clang/test/Modules/ptrauth-include-from-darwin.m (+6) - (added) clang/test/Preprocessor/ptrauth_feature.c (+10) - (added) clang/test/Sema/ptrauth-intrinsics-macro.c (+34) - (added) clang/test/Sema/ptrauth.c (+126) - (modified) llvm/docs/PointerAuth.md (+3) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 11cbdca7a268fc3..49a3934d9d082fc 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + PointerAuthentication MatrixTypes Introduction @@ -4157,6 +4158,10 @@ reordering of memory accesses and side effect instructions. Other instructions like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. +Pointer Authentication +^^ +See :doc:`PointerAuthentication`. + X86/X86-64 Language Extensions -- diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst new file mode 100644 index 000..87b8f244a2e4653 --- /dev/null +++ b/clang/docs/PointerAuthentication.rst @@ -0,0 +1,548 @@ +Pointer Authentication +== + +.. contents:: + :local: + +Introduction + + +Pointer authentication is a technology which offers strong probabilistic protection against exploiting a broad class of memory bugs to take control of program execution. When adopted consistently in a language ABI, it provides a form of relatively fine-grained control flow integrity (CFI) check that resists both return-oriented programming (ROP) and jump-oriented programming (JOP) attacks. + +While pointer authentication can be implemented purely in software, direct hardware support (e.g. as provided by ARMv8.3) can dramatically lower the execution speed and code size costs. Similarly, while pointer authentication can be implemented on any architecture, taking advantage of the (typically) excess addressing range of a target with 64-bit pointers minimizes the impact on memory performance and can allow interoperation with existing code (by disabling pointer authentication dynamically). This document will generally attempt to present the pointer authentication feature independent of any hardware implementation or ABI. Considerations that are implementation-specific are clearly identified throughout. + +Note that there are several different terms in use: + +- **Pointer authentication** is a target-independent language technology. + +- **ARMv8.3** is an AArch64 architecture revision
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/llvmbot labeled https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/llvmbot labeled https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/llvmbot labeled https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/llvmbot labeled https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha review_requested https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha review_requested https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha review_requested https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha review_requested https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha review_requested https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha review_requested https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha labeled https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha review_requested https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha review_requested https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha review_requested https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha review_requested https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha created https://github.com/llvm/llvm-project/pull/65996: This defines the basic set of pointer authentication clang builtins (provided in a new header, ptrauth.h), with diagnostics and IRGen support. The availability of the builtins is gated on a new flag, `-fptrauth-intrinsics`. Note that this only includes the basic intrinsics, and notably excludes `ptrauth_sign_constant`, `ptrauth_type_discriminator`, and `ptrauth_string_discriminator`, which need extra logic to be fully supported. This also introduces clang/docs/PointerAuthentication.rst, which describes the ptrauth model in general, as well as these builtins. (Replaces https://reviews.llvm.org/D112941) >From 6d135911787111dff1845a0c55e3d0ec0f280787 Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Mon, 11 Sep 2023 11:41:47 -0700 Subject: [PATCH] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. This defines the basic set of pointer authentication clang builtins (provided in a new header, ptrauth.h), with diagnostics and IRGen support. The availability of the builtins is gated on a new flag, `-fptrauth-intrinsics`. Note that this only includes the basic intrinsics, and notably excludes `ptrauth_sign_constant`, `ptrauth_type_discriminator`, and `ptrauth_string_discriminator`, which need extra logic to be fully supported. This also introduces clang/docs/PointerAuthentication.rst, which describes the ptrauth model in general, as well as these builtins. Co-Authored-By: Akira Hatanaka Co-Authored-By: John McCall --- clang/docs/LanguageExtensions.rst | 5 + clang/docs/PointerAuthentication.rst | 548 ++ clang/include/clang/Basic/Builtins.def| 8 + clang/include/clang/Basic/DiagnosticGroups.td | 1 + .../clang/Basic/DiagnosticSemaKinds.td| 16 + clang/include/clang/Basic/Features.def| 1 + clang/include/clang/Basic/LangOptions.def | 2 + clang/include/clang/Basic/TargetInfo.h| 6 + clang/include/clang/Driver/Options.td | 8 + clang/include/clang/Sema/Sema.h | 2 + clang/lib/Basic/Module.cpp| 4 + clang/lib/Basic/TargetInfo.cpp| 4 + clang/lib/Basic/Targets/AArch64.cpp | 6 + clang/lib/Basic/Targets/AArch64.h | 2 + clang/lib/CodeGen/CGBuiltin.cpp | 67 +++ clang/lib/Driver/ToolChains/Clang.cpp | 5 + clang/lib/Frontend/CompilerInvocation.cpp | 13 + clang/lib/Headers/CMakeLists.txt | 1 + clang/lib/Headers/module.modulemap| 5 + clang/lib/Headers/ptrauth.h | 167 ++ clang/lib/Sema/SemaChecking.cpp | 182 ++ clang/test/CodeGen/ptrauth-intrinsics.c | 73 +++ .../module.modulemap | 8 + .../ptrauth-include-from-darwin/ptrauth.h | 1 + .../ptrauth-include-from-darwin/stddef.h | 1 + .../Modules/ptrauth-include-from-darwin.m | 6 + clang/test/Preprocessor/ptrauth_feature.c | 10 + clang/test/Sema/ptrauth-intrinsics-macro.c| 34 ++ clang/test/Sema/ptrauth.c | 126 llvm/docs/PointerAuth.md | 3 + 30 files changed, 1315 insertions(+) create mode 100644 clang/docs/PointerAuthentication.rst create mode 100644 clang/lib/Headers/ptrauth.h create mode 100644 clang/test/CodeGen/ptrauth-intrinsics.c create mode 100644 clang/test/Modules/Inputs/ptrauth-include-from-darwin/module.modulemap create mode 100644 clang/test/Modules/Inputs/ptrauth-include-from-darwin/ptrauth.h create mode 100644 clang/test/Modules/Inputs/ptrauth-include-from-darwin/stddef.h create mode 100644 clang/test/Modules/ptrauth-include-from-darwin.m create mode 100644 clang/test/Preprocessor/ptrauth_feature.c create mode 100644 clang/test/Sema/ptrauth-intrinsics-macro.c create mode 100644 clang/test/Sema/ptrauth.c diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 11cbdca7a268fc3..49a3934d9d082fc 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -13,6 +13,7 @@ Clang Language Extensions BlockLanguageSpec Block-ABI-Apple AutomaticReferenceCounting + PointerAuthentication MatrixTypes Introduction @@ -4157,6 +4158,10 @@ reordering of memory accesses and side effect instructions. Other instructions like simple arithmetic may be reordered around the intrinsic. If you expect to have no reordering at all, use inline assembly instead. +Pointer Authentication +^^ +See :doc:`PointerAuthentication`. + X86/X86-64 Language Extensions -- diff --git a/clang/docs/PointerAuthentication.rst b/clang/docs/PointerAuthentication.rst new file mode 100644 index 000..87b8f244a2e4653 --- /dev/null +++ b/clang/docs/PointerAuthentication.rst @@ -0,0 +1,548 @@ +Pointer Authentication
[clang] [AArch64][PAC] Support ptrauth builtins and -fptrauth-intrinsics. (PR #65996)
https://github.com/ahmedbougacha labeled https://github.com/llvm/llvm-project/pull/65996 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits