[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
atrosinenko wrote: My local tests look good too. Both this PR and #176187 look good to me, with the only concern that changing where the function attributes are attached to the function might deserve its own follow-up PR. Thank you very much for all the fixes! BTW considering the tests, in case anyone else stumbles upon a failure in `MultiSource/Benchmarks/Trimaran/netbench-url/netbench-url.test`, this seems to be the issue in the test itself, see #158628 for the details. https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
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 origin/main HEAD --extensions c,h,cpp --
clang/test/CodeGen/aarch64-sign-return-address-harden.c
clang/test/Frontend/aarch64-harden-pac-ret-err.c
clang/test/Sema/aarch64-harden-pac-ret-attr-err-warn.c
clang/test/Sema/aarch64-harden-pac-ret-attr-ignored.c
clang/test/Sema/aarch64-harden-pac-ret-attr.c
clang/include/clang/Basic/LangOptions.h clang/include/clang/Basic/TargetInfo.h
clang/lib/Basic/Targets/AArch64.cpp clang/lib/Basic/Targets/AArch64.h
clang/lib/Basic/Targets/ARM.cpp clang/lib/Basic/Targets/ARM.h
clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/TargetInfo.cpp
clang/lib/CodeGen/Targets/AArch64.cpp clang/lib/CodeGen/Targets/ARM.cpp
clang/lib/Driver/ToolChains/Clang.cpp clang/lib/Sema/SemaDeclAttr.cpp
clang/test/CodeGen/AArch64/sign-return-address.c
clang/test/Driver/aarch64-security-options.c
clang/test/Driver/arm-security-options.c --diff_from_common_commit
``
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
View the diff from clang-format here.
``diff
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 6bcdf1e42..fbe710329 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3701,7 +3701,8 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc,
StringRef AttrStr) {
if (ParsedAttrs.BranchProtection.empty()) {
if (!ParsedAttrs.SignReturnAddrHardening.empty())
- return Diag(LiteralLoc,
diag::warn_attribute_harden_pac_ret_requires_pac_ret);
+ return Diag(LiteralLoc,
+ diag::warn_attribute_harden_pac_ret_requires_pac_ret);
return false;
}
``
https://github.com/llvm/llvm-project/pull/176171
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -3699,13 +3699,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc,
StringRef AttrStr) {
<< Unsupported << None << CurFeature << Target;
}
+ if (ParsedAttrs.BranchProtection.empty()) {
+if (!ParsedAttrs.SignReturnAddrHardening.empty())
+ Diag(LiteralLoc, diag::warn_attribute_harden_pac_ret_requires_pac_ret);
+return false;
vhscampos wrote:
Fixed. Thanks
https://github.com/llvm/llvm-project/pull/176171
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -3699,13 +3699,17 @@ bool Sema::checkTargetAttr(SourceLocation LiteralLoc,
StringRef AttrStr) {
<< Unsupported << None << CurFeature << Target;
}
+ if (ParsedAttrs.BranchProtection.empty()) {
+if (!ParsedAttrs.SignReturnAddrHardening.empty())
+ Diag(LiteralLoc, diag::warn_attribute_harden_pac_ret_requires_pac_ret);
+return false;
atrosinenko wrote:
Oh, this should probably use `return`:
```suggestion
if (!ParsedAttrs.SignReturnAddrHardening.empty())
return Diag(LiteralLoc,
diag::warn_attribute_harden_pac_ret_requires_pac_ret);
return false;
```
As far as I can see, `SemaBase::Diag` returns `Sema::SemaDiagnosticBuilder`
which is converted to boolean `true` iff the diagnostic is "immediate" (which
is always the case except for some CUDA code). The only caller of
`Sema::checkTargetAttr` is static
[`handleTargetAttr`](https://github.com/llvm/llvm-project/blob/33cc998157406abe5c1319e1532bd401dd0aafb6/clang/lib/Sema/SemaDeclAttr.cpp#L3741)
function in the same file that uses the returned value to decide whether to
skip the `target("...")` attribute.
Consider the following example:
```cpp
int f1() { return 1; }
__attribute__((target("branch-protection=bti")))
int f2() { return 1; }
__attribute__((target("cpu=neoverse-v2,branch-protection=pac-ret,harden-pac-ret=load-return-address")))
int f3() { return 1; }
__attribute__((target("cpu=neoverse-v2,branch-protection=bti,harden-pac-ret=load-return-address")))
int f4() { return 1; }
__attribute__((target("cpu=neoverse-v2,harden-pac-ret=load-return-address")))
int f5() { return 1; }
```
Here, `f1` should have a short list of attributes at the LLVM IR level, `f2`
should have the same attributes plus `"branch-target-enforcement"`. `f3` should
have pac-ret and pac-ret hardening enabled and have a long list of supported
extensions in its `"target-features"="..."` attribute. Considering `f4` and
`f5`, according to the warning text, I would expect them to have the same set
of function attributes as `f0` has (because of `'target' attribute ignored`).
This is actually the case for `f4`, but not for `f5`, even though the same
warning is emitted for both
```
/temp/test.c:9:23: warning: 'harden-pac-ret' attribute requires
'branch-protection=pac-ret'; 'target' attribute ignored [-Wignored-attributes]
9 |
__attribute__((target("cpu=neoverse-v2,branch-protection=bti,harden-pac-ret=load-return-address")))
| ^
/temp/test.c:12:23: warning: 'harden-pac-ret' attribute requires
'branch-protection=pac-ret'; 'target' attribute ignored [-Wignored-attributes]
12 |
__attribute__((target("cpu=neoverse-v2,harden-pac-ret=load-return-address")))
| ^
```
PS: This probably requires adding another test case, as the existing ones pass
whether `return` is inserted or not.
https://github.com/llvm/llvm-project/pull/176171
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
https://github.com/atrosinenko approved this pull request. https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -1660,6 +1660,11 @@ void CodeGenModule::Release() {
LangOpts.PointerAuthInitFiniAddressDiscrimination);
}
+if (LangOpts.isSignReturnAddressHardenWithLoadReturnAddress())
+ getModule().addModuleFlag(
+ llvm::Module::Error, "sign-return-address-harden",
+ llvm::MDString::get(getLLVMContext(), "load-return-address"));
+
atrosinenko wrote:
It would probably be more straightforward to define a "none vs. anything"
getter instead `isSignReturnAddressHardenWithLoadReturnAddress` and use
something like this
```cpp
if (LangOpts.isSignReturnAddressHardenEnabled()) {
TargetInfo::BranchProtectionInfo BPI(LangOpts);
getModule().addModuleFlag(
llvm::Module::Error, "sign-return-address-harden",
llvm::MDString::get(getLLVMContext(),
BPI.getSignReturnAddressHardeningStr()));
}
```
https://github.com/llvm/llvm-project/pull/176171
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -226,6 +227,15 @@ void TargetCodeGenInfo::setBranchProtectionFnAttributes(
F.removeFnAttr("sign-return-address-key");
}
+ if (BPI.SignReturnAddressHardening ==
+ LangOptions::SignReturnAddressHardeningKind::None) {
+F.removeFnAttr("sign-return-address-harden");
+ } else if (BPI.SignReturnAddr !=
+ LangOptions::SignReturnAddressScopeKind::None) {
+F.addFnAttr("sign-return-address-harden",
+BPI.getSignReturnAddressHardeningStr());
+ }
atrosinenko wrote:
I wonder if an easier approach can be used (same as in
`initBranchProtectionFnAttributes`):
* if `BPI.SignReturnAddressHardening` **is** None, remove the attribute
* if `BPI.SignReturnAddressHardening` **is not** None, set the attribute
Alternatively, if it is important to never set "sign-return-address-harden"
function attribute without the "sign-return-address" attribute (and at the same
time we cannot rely on this invariant holding for `BPI` for some reason), then
the existing approach lacks the final `else` branch containing one more
`removeFnAttr`. The `initBranchProtectionFnAttributes` should probably be
updated then as well.
PS: Strictly speaking, the other calls to `removeFnAttr` in this function are
performed after checking if the attribute exists with `hasFnAttribute`. On the
other hand, it looks like `removeFnAttr` checks this by itself down the stack,
so maybe these are the *other* calls to `removeFnAttr` that have to be
simplified someday later...
https://github.com/llvm/llvm-project/pull/176171
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -764,6 +771,13 @@ class LangOptions : public LangOptionsBase {
return getSignReturnAddressScope() == SignReturnAddressScopeKind::All;
}
+ /// Check if return address signing hardening is enabled and uses load from
+ /// the return address.
+ bool isSignReturnAddressHardenWithLoadReturnAddress() const {
atrosinenko wrote:
Restoring the "is hardening enabled?" getter that checks for `... != None`
could possibly be more straightforward, see below.
https://github.com/llvm/llvm-project/pull/176171
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
https://github.com/atrosinenko commented: Sorry for nit-picking iteratively, but here are a few more comments :) https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -170,6 +170,11 @@ Makes programs 10x faster by doing Special New Thing. ### Changes to the AArch64 Backend +* Added support for hardening return address signing against PACMAN attacks. + Functions with the `"sign-return-address-harden"="load-return-address"` + attribute perform a load of the return address before returning, reducing the atrosinenko wrote: [nit] "load **from** the return address" https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
https://github.com/atrosinenko edited https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
vhscampos wrote: Thanks for the most recent review @atrosinenko . I have addressed your comments. https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
https://github.com/vhscampos converted_to_draft https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -0,0 +1,175 @@ +## + Return Address Signing Hardening vhscampos wrote: You make a good point. Thanks for the suggestion. I've changed the naming. https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -0,0 +1,175 @@
+##
+ Return Address Signing Hardening
+##
+
+.. contents::
+ :local:
+
+**
+ Introduction
+**
+
+Return Address Signing Hardening is a mitigation against the PACMAN attack,
+which aims to bypass Pointer Authentication on AArch64 targets. The hardening
+mechanism described here is specific to pointer authentication of return
+addresses.
+
+Return Address Signing, also known as Pointer Authentication Code (PAC-RET), is
+a feature devised to protect programs against Return Oriented Programming
(ROP),
+in which attackers may hijack the return address of functions in order to
direct
+execution to malicious code.
+
+PAC-RET can be enabled via different command-line options:
+
+ - ``-mbranch-protection=`` with ``pac-ret``, ``pac-ret+leaf`` or
+ ``standard`` as value.
+ - ``-msign-return-address=`` with ``non-leaf`` or ``all`` as value.
+ - ``-fptrauth-returns``.
+
+More information can be found in :doc:`Pointer Authentication
+`.
+
+Return Address Signing Hardening is a mechanism to strenghthen Return Address
+Signing against the PACMAN attack in AArch64 targets. It can be enabled with
+``-mharden-pac-ret=load-return-address``.
+
+***
+ PACMAN attack
+***
+
+PACMAN is an attack that aims to extract valuable information about pointer
+authentication codes using side-channels in speculative execution.
+
+It is performed with the use of gadgets to try and guess PAC codes. These
+guesses raise no faults because they are done in speculation. By observing the
+effects of the guessed PAC code on the processor's cache, it might be possible
+to determine the valid PAC code for the address to which the attacker wants the
+program to return.
+
+A usual PACMAN gadget looks like this:
+
+.. code:: C
+
+ void function() {
+ ...
+ if (condition)
+ return;
+ ...
+ }
+
+Such code would be compiled to:
+
+.. code:: asm
+
+ paciasp
+ ...
+ cbz w0, .LBB0_2
+ autiasp
+ ret
+ ...
+
+This code segment may be used as a gadget. A speculative execution of this
+segment can happen as follows:
+
+ - If the Link Register (LR) has the right PAC code, ``autiasp`` will
succeed
+ and strip the PAC code out of it. The processor's instruction fetcher
will
+ then bring the code after the return into the cache (that is, the
+ instructions located at the address pointed by LR).
+
+ - If the LR has the wrong PAC code, ``autiasp`` will not succeed and hence
+ will write a predefined error value to the LR's higher bits. Because of
+ this, the instruction fetcher will not bring the code after the return
+ into the cache.
+
+This difference in behavior is what drives the PACMAN attack. An attacker can
+try to guess PAC codes and monitor cache behavior until the code after the
+return is observed to have been brought into the cache.
+
+Details can be found in https://pacmanattack.com.
+
+***
+ Hardening
+***
+
+In order to mitigate the PACMAN attack, a hardening mechanism can be enabled
+with ``-mharden-pac-ret=load-return-address``.
+
+.. code:: asm
+
+ paciasp
+ ...
+ cbz w0, .LBB0_2
+ autiasp
+ mov x8, x30
+ xpaclri
+ ldr w30, [x30]
+ ret x8
+ ...
+
+The idea is to always bring the code after the return into cache (the
+instructions located at the address pointed by LR), therefore minimizing the
+difference between a speculative execution with a correct PAC code and with an
+incorrect one.
+
+ - ``autiasp`` performs the authentication step.
+ - ``mov x8, x30`` copies the return address (LR and x30 are synonyms) to a
+ temporary.
+ - ``xpaclri`` strips the PAC code out of the return address in x30.
+ - ``ldr w30, [x30]`` performs a load of the return address in x30.
+ - ``ret x8`` returns to the authenticated return address.
+
+The load operation brings the code into the cache even if the authentication
+step fails. As a consequence, in either case the code is loaded into the cache.
+Furthermore, the return operation uses the original return address before
+stripping, so the return address protection is still kept in place in a normal
+non-speculative execution.
+
+If FEAT_PAUTH is present, the code sequence can use instructions only available
+with said feature with no change in semantics:
+
+.. code:: asm
+
+ autiasp
+ mov x8, x30
+ xpaci x8
+ ldr w8, [x8]
+ ret
+
+*
+ Command-line option
+*
+
+Return address signing hardening can be enabled at module level with
+``-mharden-pac-ret=load-return-address``. It requires PAC-RET to be enabled at
+module level as well.
vhscampos wrote:
Done. Originally I wasn't using module flags at all, only relying on function
attributes. But if we want compiler-created functions to have the hardening if
enabled, we need the module flags.
The
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -0,0 +1,175 @@ +## + Return Address Signing Hardening +## + +.. contents:: + :local: + +** + Introduction +** + +Return Address Signing Hardening is a mitigation against the PACMAN attack, +which aims to bypass Pointer Authentication on AArch64 targets. The hardening +mechanism described here is specific to pointer authentication of return +addresses. + +Return Address Signing, also known as Pointer Authentication Code (PAC-RET), is vhscampos wrote: Done https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -216,16 +216,29 @@ void TargetCodeGenInfo::setBranchProtectionFnAttributes(
// Called on already created and initialized function where attributes
already
// set from command line attributes but some might need to be removed as the
// actual BPI is different.
+
if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) {
F.addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
F.addFnAttr("sign-return-address-key", BPI.getSignKeyStr());
+if (BPI.SignReturnAddressHardening !=
+LangOptions::SignReturnAddressHardeningKind::None)
+ F.addFnAttr("sign-return-address-harden",
+ BPI.getSignReturnAddressHardeningStr());
vhscampos wrote:
Done. Thank you
https://github.com/llvm/llvm-project/pull/176171
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -0,0 +1,175 @@
+##
+ Return Address Signing Hardening
+##
+
+.. contents::
+ :local:
+
+**
+ Introduction
+**
+
+Return Address Signing Hardening is a mitigation against the PACMAN attack,
+which aims to bypass Pointer Authentication on AArch64 targets. The hardening
+mechanism described here is specific to pointer authentication of return
+addresses.
+
+Return Address Signing, also known as Pointer Authentication Code (PAC-RET), is
+a feature devised to protect programs against Return Oriented Programming
(ROP),
+in which attackers may hijack the return address of functions in order to
direct
+execution to malicious code.
+
+PAC-RET can be enabled via different command-line options:
+
+ - ``-mbranch-protection=`` with ``pac-ret``, ``pac-ret+leaf`` or
+ ``standard`` as value.
+ - ``-msign-return-address=`` with ``non-leaf`` or ``all`` as value.
+ - ``-fptrauth-returns``.
+
+More information can be found in :doc:`Pointer Authentication
+`.
+
+Return Address Signing Hardening is a mechanism to strenghthen Return Address
+Signing against the PACMAN attack in AArch64 targets. It can be enabled with
+``-mharden-pac-ret=load-return-address``.
+
+***
+ PACMAN attack
+***
+
+PACMAN is an attack that aims to extract valuable information about pointer
+authentication codes using side-channels in speculative execution.
+
+It is performed with the use of gadgets to try and guess PAC codes. These
+guesses raise no faults because they are done in speculation. By observing the
+effects of the guessed PAC code on the processor's cache, it might be possible
+to determine the valid PAC code for the address to which the attacker wants the
+program to return.
+
+A usual PACMAN gadget looks like this:
+
+.. code:: C
+
+ void function() {
+ ...
+ if (condition)
+ return;
+ ...
+ }
+
+Such code would be compiled to:
+
+.. code:: asm
+
+ paciasp
+ ...
+ cbz w0, .LBB0_2
+ autiasp
+ ret
+ ...
+
+This code segment may be used as a gadget. A speculative execution of this
+segment can happen as follows:
+
+ - If the Link Register (LR) has the right PAC code, ``autiasp`` will
succeed
+ and strip the PAC code out of it. The processor's instruction fetcher
will
+ then bring the code after the return into the cache (that is, the
+ instructions located at the address pointed by LR).
+
+ - If the LR has the wrong PAC code, ``autiasp`` will not succeed and hence
+ will write a predefined error value to the LR's higher bits. Because of
+ this, the instruction fetcher will not bring the code after the return
+ into the cache.
+
+This difference in behavior is what drives the PACMAN attack. An attacker can
+try to guess PAC codes and monitor cache behavior until the code after the
+return is observed to have been brought into the cache.
+
+Details can be found in https://pacmanattack.com.
+
+***
+ Hardening
+***
+
+In order to mitigate the PACMAN attack, a hardening mechanism can be enabled
+with ``-mharden-pac-ret=load-return-address``.
+
+.. code:: asm
+
+ paciasp
+ ...
+ cbz w0, .LBB0_2
+ autiasp
+ mov x8, x30
+ xpaclri
+ ldr w30, [x30]
+ ret x8
+ ...
+
+The idea is to always bring the code after the return into cache (the
+instructions located at the address pointed by LR), therefore minimizing the
+difference between a speculative execution with a correct PAC code and with an
+incorrect one.
+
+ - ``autiasp`` performs the authentication step.
+ - ``mov x8, x30`` copies the return address (LR and x30 are synonyms) to a
+ temporary.
+ - ``xpaclri`` strips the PAC code out of the return address in x30.
+ - ``ldr w30, [x30]`` performs a load of the return address in x30.
+ - ``ret x8`` returns to the authenticated return address.
+
+The load operation brings the code into the cache even if the authentication
+step fails. As a consequence, in either case the code is loaded into the cache.
+Furthermore, the return operation uses the original return address before
+stripping, so the return address protection is still kept in place in a normal
+non-speculative execution.
+
+If FEAT_PAUTH is present, the code sequence can use instructions only available
+with said feature with no change in semantics:
+
+.. code:: asm
+
+ autiasp
+ mov x8, x30
+ xpaci x8
+ ldr w8, [x8]
+ ret
+
+*
+ Command-line option
+*
+
+Return address signing hardening can be enabled at module level with
vhscampos wrote:
Done. Thank you
https://github.com/llvm/llvm-project/pull/176171
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -35,6 +38,58 @@ // WARN-NOT: warning: ignoring '-mbranch-protection=' option because the 'aarch64' architecture does not support it [-Wbranch-protection] +// RUN: %clang -target aarch64 -c %s -### 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=ABSENT-RA-HARDEN + +// RUN: %clang -target aarch64 -c %s -### -mharden-pac-ret=none 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=NO-RA-HARDEN + +// RUN: %clang -target aarch64 -c %s -### -mharden-pac-ret=load-return-address 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=NO-RA-HARDEN + +// RUN: %clang -target aarch64 -c %s -### -mbranch-protection=none -mharden-pac-ret=none 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=NO-RA-HARDEN +// RUN: %clang -target arm64-apple-darwin -c %s -### -fno-ptrauth-returns -mharden-pac-ret=none 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=NO-RA-HARDEN + +// RUN: %clang -target aarch64 -c %s -### -mbranch-protection=none -mharden-pac-ret=load-return-address 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=NO-RA-HARDEN +// RUN: %clang -target arm64-apple-darwin -c %s -### -fno-ptrauth-returns -mharden-pac-ret=load-return-address 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=NO-RA-HARDEN + +// RUN: %clang -target aarch64 -c %s -### -mbranch-protection=pac-ret -mharden-pac-ret=none 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=RA-HARDEN-NONE +// RUN: %clang -target arm64-apple-darwin -c %s -### -fptrauth-returns -mharden-pac-ret=none 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=RA-HARDEN-NONE + +// RUN: %clang -target aarch64 -c %s -### -mbranch-protection=pac-ret -mharden-pac-ret=load-return-address 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=RA-HARDEN-LRA +// RUN: %clang -target arm64-apple-darwin -c %s -### -fptrauth-returns -mharden-pac-ret=load-return-address 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=RA-HARDEN-LRA + +// RUN: %clang -target aarch64 -c %s -### -mbranch-protection=standard -mharden-pac-ret=none 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=RA-HARDEN-NONE + +// RUN: %clang -target aarch64 -c %s -### -mbranch-protection=standard -mharden-pac-ret=load-return-address 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=RA-HARDEN-LRA + +// RUN: not %clang -target aarch64 -c %s -### -mbranch-protection=standard -mharden-pac-ret=foo 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=BAD-HARDEN-PROTECTION +// RUN: not %clang -target arm64-apple-darwin -c %s -### -fptrauth-returns -mharden-pac-ret=foo 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=BAD-HARDEN-PROTECTION + +// RUN: not %clang -target aarch64 -c %s -### -mbranch-protection=standard -mharden-pac-ret=load-return-address -mexecute-only 2>&1 | \ +// RUN: FileCheck %s --check-prefixes=RA-HARDEN-INCOMPATIBLE-EXEC-ONLY +// RUN: %clang -target aarch64 -c %s -### -mbranch-protection=standard -mharden-pac-ret=none -mexecute-only vhscampos wrote: Done. Thank you https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
https://github.com/vhscampos updated https://github.com/llvm/llvm-project/pull/176171 >From 4f775ae42fbc2729697b32ed5b5310a86f9cbfc4 Mon Sep 17 00:00:00 2001 From: Victor Campos Date: Tue, 13 Jan 2026 20:39:02 + Subject: [PATCH 1/6] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening This patch introduces a new command-line option to enable the AArch64 A-profile's Sign Return Address Hardening. It also introduces a new function attribute with the same naming as the new command-line option. At the time of this patch, this new option enables the hardening against the PACMAN attack [1] using a load of the return address [2]. The new option, -mharden-pac-ret, can take one of two values: - none: disable hardening. (The default if the option is absent) - load-return-address: enables hardening using the mitigation based on load of return address. The corresponding function attribute takes the option and its possible values using the same naming. 1: https://pacmanattack.com 2: https://developer.arm.com/documentation/101754/0624/armclang-Reference/armclang-Command-line-Options/-mharden-pac-ret --- .../clang/Basic/DiagnosticDriverKinds.td | 2 + .../clang/Basic/DiagnosticSemaKinds.td| 5 +++ clang/include/clang/Basic/LangOptions.def | 2 + clang/include/clang/Basic/LangOptions.h | 12 ++ clang/include/clang/Basic/TargetInfo.h| 22 ++ clang/include/clang/Options/Options.td| 9 clang/lib/Basic/Targets/AArch64.cpp | 16 +++ clang/lib/Basic/Targets/AArch64.h | 2 + clang/lib/CodeGen/TargetInfo.cpp | 4 ++ clang/lib/CodeGen/Targets/AArch64.cpp | 3 ++ clang/lib/Driver/ToolChains/Clang.cpp | 22 +- clang/lib/Sema/SemaDeclAttr.cpp | 18 +++- .../aarch64-sign-return-address-harden.c | 13 ++ clang/test/Driver/aarch64-security-options.c | 30 + clang/test/Driver/arm-security-options.c | 19 .../Frontend/aarch64-harden-pac-ret-err.c | 3 ++ .../aarch64-harden-pac-ret-attr-err-warn.c| 21 + clang/test/Sema/aarch64-harden-pac-ret-attr.c | 43 +++ 18 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGen/aarch64-sign-return-address-harden.c create mode 100644 clang/test/Frontend/aarch64-harden-pac-ret-err.c create mode 100644 clang/test/Sema/aarch64-harden-pac-ret-attr-err-warn.c create mode 100644 clang/test/Sema/aarch64-harden-pac-ret-attr.c diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index db0f521b73544..d16fbd45f104e 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -544,6 +544,8 @@ def warn_ignoring_verify_debuginfo_preserve_export : Warning< InGroup; def warn_unsupported_branch_protection: Warning < "invalid branch protection option '%0' in '%1'">, InGroup; +def warn_harden_pac_ret_requires_pac_ret: Warning< + "ignoring '-mharden-pac-ret' as it requires return address signing">, InGroup; def err_sls_hardening_arm_not_supported : Error< "-mharden-sls is only supported on armv7-a or later">; def warn_drv_large_data_threshold_invalid_code_model: Warning< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5cbbc7d130c99..fdfe7792441b9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3384,6 +3384,11 @@ def err_invalid_branch_protection_spec : Error< "invalid or misplaced branch protection specification '%0'">; def warn_unsupported_branch_protection_spec : Warning< "unsupported branch protection specification '%0'">, InGroup; +def warn_attribute_harden_pac_ret_requires_pac_ret: Warning< + "'harden-pac-ret' attribute requires 'branch-protection=pac-ret'; 'target' attribute ignored">, + InGroup; +def err_invalid_harden_pac_ret_spec : Error< + "invalid or misplaced pac-ret hardening specification '%0'">; def err_attribute_invalid_atomic_argument : Error< "invalid argument '%0' to atomic attribute; valid options are: " "'remote_memory', 'fine_grained_memory', 'ignore_denormal_mode' (optionally " diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 8cba1dbaee24e..f3c5613d3dab7 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -454,6 +454,8 @@ ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAd "Scope of return address signing") ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddressKeyKind::AKey, NotCompatible, "Key used for return address signing") +ENUM_LANGOPT(SignReturnAddressHardening, SignReturnAddressHardeningKind, 1, +
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
https://github.com/atrosinenko edited https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
github-actions[bot] wrote: # :penguin: Linux x64 Test Results * 90532 tests passed * 1715 tests skipped * 1 test failed ## Failed Tests (click on a test name to see its output) ### lldb-api lldb-api.tools/lldb-dap/stepInTargets/TestDAP_stepInTargets.py ``` Script: -- /usr/bin/python3 /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --env LLVM_INCLUDE_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include --env LLVM_TOOLS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --libcxx-include-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/c++/v1 --libcxx-include-target-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/x86_64-unknown-linux-gnu/c++/v1 --libcxx-library-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib/x86_64-unknown-linux-gnu --triple x86_64-unknown-linux-gnu --build-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build --lldb-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build/module-cache-lldb/lldb-api --clang-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build/module-cache-clang/lldb-api --executable /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/lldb --lldb-python-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/local/lib/python3.12/dist-packages --compiler /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/clang --dsymutil /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --lldb-obj-root /home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/lldb --lldb-libs-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --cmake-build-type Release /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/tools/lldb-dap/stepInTargets -p TestDAP_stepInTargets.py -- Exit Code: -9 Timeout: Reached timeout of 1200 seconds Command Output (stdout): -- Skipping the following test categories: msvcstl, dsym, pdb, gmodules, debugserver, objc -- Command Output (stderr): -- PASS: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test_basic (TestDAP_stepInTargets.TestDAP_stepInTargets.test_basic) UNSUPPORTED: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test_supported_capability_other_archs (TestDAP_stepInTargets.TestDAP_stepInTargets.test_supported_capability_other_archs) (skipping due to the following parameter(s): architecture) Log Files: - /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets/SkippedTest_test_supported_capability_other_archs.log FAIL: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test_supported_capability_x86_arch (TestDAP_stepInTargets.TestDAP_stepInTargets.test_supported_capability_x86_arch) Log Files: - /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build/tools/lldb-dap/stepInTargets/TestDAP_stepInTargets/Error_test_supported_capability_x86_arch.log == ERROR: test_supported_capability_x86_arch (TestDAP_stepInTargets.TestDAP_stepInTargets.test_supported_capability_x86_arch) -- Traceback (most recent call last): File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/lldbtest.py", line 1203, in tearDown hook() # try the plain call and hope it works ^^ File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/testcase.py", line 114, in cleanup_session session.disconnect(terminateDebuggee=True) File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/session_helpers.py", line 1717, in disconnect response = self.send_request(args).result() File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/session.py", line 99, in result response = self.result_or_error() ^^ File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/tools/lldb_dap/session.py", line 116, in result_or_error raw = self._future.result(timeout=self._timeout) ^^ File
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
https://github.com/vhscampos updated https://github.com/llvm/llvm-project/pull/176171 >From 4f775ae42fbc2729697b32ed5b5310a86f9cbfc4 Mon Sep 17 00:00:00 2001 From: Victor Campos Date: Tue, 13 Jan 2026 20:39:02 + Subject: [PATCH 1/5] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening This patch introduces a new command-line option to enable the AArch64 A-profile's Sign Return Address Hardening. It also introduces a new function attribute with the same naming as the new command-line option. At the time of this patch, this new option enables the hardening against the PACMAN attack [1] using a load of the return address [2]. The new option, -mharden-pac-ret, can take one of two values: - none: disable hardening. (The default if the option is absent) - load-return-address: enables hardening using the mitigation based on load of return address. The corresponding function attribute takes the option and its possible values using the same naming. 1: https://pacmanattack.com 2: https://developer.arm.com/documentation/101754/0624/armclang-Reference/armclang-Command-line-Options/-mharden-pac-ret --- .../clang/Basic/DiagnosticDriverKinds.td | 2 + .../clang/Basic/DiagnosticSemaKinds.td| 5 +++ clang/include/clang/Basic/LangOptions.def | 2 + clang/include/clang/Basic/LangOptions.h | 12 ++ clang/include/clang/Basic/TargetInfo.h| 22 ++ clang/include/clang/Options/Options.td| 9 clang/lib/Basic/Targets/AArch64.cpp | 16 +++ clang/lib/Basic/Targets/AArch64.h | 2 + clang/lib/CodeGen/TargetInfo.cpp | 4 ++ clang/lib/CodeGen/Targets/AArch64.cpp | 3 ++ clang/lib/Driver/ToolChains/Clang.cpp | 22 +- clang/lib/Sema/SemaDeclAttr.cpp | 18 +++- .../aarch64-sign-return-address-harden.c | 13 ++ clang/test/Driver/aarch64-security-options.c | 30 + clang/test/Driver/arm-security-options.c | 19 .../Frontend/aarch64-harden-pac-ret-err.c | 3 ++ .../aarch64-harden-pac-ret-attr-err-warn.c| 21 + clang/test/Sema/aarch64-harden-pac-ret-attr.c | 43 +++ 18 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGen/aarch64-sign-return-address-harden.c create mode 100644 clang/test/Frontend/aarch64-harden-pac-ret-err.c create mode 100644 clang/test/Sema/aarch64-harden-pac-ret-attr-err-warn.c create mode 100644 clang/test/Sema/aarch64-harden-pac-ret-attr.c diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index db0f521b73544..d16fbd45f104e 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -544,6 +544,8 @@ def warn_ignoring_verify_debuginfo_preserve_export : Warning< InGroup; def warn_unsupported_branch_protection: Warning < "invalid branch protection option '%0' in '%1'">, InGroup; +def warn_harden_pac_ret_requires_pac_ret: Warning< + "ignoring '-mharden-pac-ret' as it requires return address signing">, InGroup; def err_sls_hardening_arm_not_supported : Error< "-mharden-sls is only supported on armv7-a or later">; def warn_drv_large_data_threshold_invalid_code_model: Warning< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5cbbc7d130c99..fdfe7792441b9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3384,6 +3384,11 @@ def err_invalid_branch_protection_spec : Error< "invalid or misplaced branch protection specification '%0'">; def warn_unsupported_branch_protection_spec : Warning< "unsupported branch protection specification '%0'">, InGroup; +def warn_attribute_harden_pac_ret_requires_pac_ret: Warning< + "'harden-pac-ret' attribute requires 'branch-protection=pac-ret'; 'target' attribute ignored">, + InGroup; +def err_invalid_harden_pac_ret_spec : Error< + "invalid or misplaced pac-ret hardening specification '%0'">; def err_attribute_invalid_atomic_argument : Error< "invalid argument '%0' to atomic attribute; valid options are: " "'remote_memory', 'fine_grained_memory', 'ignore_denormal_mode' (optionally " diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 8cba1dbaee24e..f3c5613d3dab7 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -454,6 +454,8 @@ ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAd "Scope of return address signing") ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddressKeyKind::AKey, NotCompatible, "Key used for return address signing") +ENUM_LANGOPT(SignReturnAddressHardening, SignReturnAddressHardeningKind, 1, +
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
vhscampos wrote: Added new entries to Clang and LLVM release notes as well. https://github.com/llvm/llvm-project/pull/176171 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
@@ -0,0 +1,178 @@
+##
+ Return Address Signing Hardening
+##
+
+.. contents::
+ :local:
+
+**
+ Introduction
+**
+
+Return Address Signing Hardening is a mitigation against the PACMAN
+attack, which aims to bypass Pointer Authentication on AArch64 targets.
+The hardening mechanism described here is specific to pointer
+authentication of return addresses.
+
+Return Address Signing, also known as Pointer Authentication Code
+(PAC-RET), is a feature devised to protect programs against Return
+Oriented Programming (ROP), in which attackers may hijack the return
+address of functions in order to direct execution to malicious code.
+
+PAC-RET can be enabled via different command-line options:
+
+ - ``-mbranch-protection=`` with ``pac-ret``, ``pac-ret+leaf`` or
+ ``standard`` as value.
+ - ``-msign-return-address=`` with ``non-leaf`` or ``all`` as value.
+ - ``-fptrauth-returns``.
+
+More information can be found in :doc:`Pointer Authentication
+`.
+
+Return Address Signing Hardening is a mechanism to strenghthen Return
+Address Signing against the PACMAN attack in AArch64 targets. It can be
+enabled with ``-mharden-pac-ret=load-return-address``.
+
+***
+ PACMAN attack
+***
+
+PACMAN is an attack that aims to extract valuable information about
+pointer authentication codes using side-channels in speculative
+execution.
+
+It is performed with the use of gadgets to try and guess PAC codes.
+These guesses raise no faults because they are done in speculation. By
+observing the effects of the guessed PAC code on the processor's cache,
+it might be possible to determine the valid PAC code for the address to
+which the attacker wants the program to return.
+
+A usual PACMAN gadget looks like this:
+
+.. code:: C
+
+ void function() {
+ ...
+ if (condition)
+ return;
+ ...
+ }
+
+Such code would be compiled to:
+
+.. code:: asm
+
+ paciasp
+ ...
+ cbz w0, .LBB0_2
+ autiasp
+ ret
+ ...
+
+This code segment may be used as a gadget. A speculative execution of
+this segment can happen as follows:
+
+ - If the Link Register (LR) has the right PAC code, ``autiasp`` will
+ succeed and strip the PAC code out of the it. The processor's
vhscampos wrote:
Thanks. Fixed. I also ran an rst formatter on this file just to tidy it up a
bit.
https://github.com/llvm/llvm-project/pull/176171
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
https://github.com/vhscampos updated https://github.com/llvm/llvm-project/pull/176171 >From 4f775ae42fbc2729697b32ed5b5310a86f9cbfc4 Mon Sep 17 00:00:00 2001 From: Victor Campos Date: Tue, 13 Jan 2026 20:39:02 + Subject: [PATCH 1/5] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening This patch introduces a new command-line option to enable the AArch64 A-profile's Sign Return Address Hardening. It also introduces a new function attribute with the same naming as the new command-line option. At the time of this patch, this new option enables the hardening against the PACMAN attack [1] using a load of the return address [2]. The new option, -mharden-pac-ret, can take one of two values: - none: disable hardening. (The default if the option is absent) - load-return-address: enables hardening using the mitigation based on load of return address. The corresponding function attribute takes the option and its possible values using the same naming. 1: https://pacmanattack.com 2: https://developer.arm.com/documentation/101754/0624/armclang-Reference/armclang-Command-line-Options/-mharden-pac-ret --- .../clang/Basic/DiagnosticDriverKinds.td | 2 + .../clang/Basic/DiagnosticSemaKinds.td| 5 +++ clang/include/clang/Basic/LangOptions.def | 2 + clang/include/clang/Basic/LangOptions.h | 12 ++ clang/include/clang/Basic/TargetInfo.h| 22 ++ clang/include/clang/Options/Options.td| 9 clang/lib/Basic/Targets/AArch64.cpp | 16 +++ clang/lib/Basic/Targets/AArch64.h | 2 + clang/lib/CodeGen/TargetInfo.cpp | 4 ++ clang/lib/CodeGen/Targets/AArch64.cpp | 3 ++ clang/lib/Driver/ToolChains/Clang.cpp | 22 +- clang/lib/Sema/SemaDeclAttr.cpp | 18 +++- .../aarch64-sign-return-address-harden.c | 13 ++ clang/test/Driver/aarch64-security-options.c | 30 + clang/test/Driver/arm-security-options.c | 19 .../Frontend/aarch64-harden-pac-ret-err.c | 3 ++ .../aarch64-harden-pac-ret-attr-err-warn.c| 21 + clang/test/Sema/aarch64-harden-pac-ret-attr.c | 43 +++ 18 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGen/aarch64-sign-return-address-harden.c create mode 100644 clang/test/Frontend/aarch64-harden-pac-ret-err.c create mode 100644 clang/test/Sema/aarch64-harden-pac-ret-attr-err-warn.c create mode 100644 clang/test/Sema/aarch64-harden-pac-ret-attr.c diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index db0f521b73544..d16fbd45f104e 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -544,6 +544,8 @@ def warn_ignoring_verify_debuginfo_preserve_export : Warning< InGroup; def warn_unsupported_branch_protection: Warning < "invalid branch protection option '%0' in '%1'">, InGroup; +def warn_harden_pac_ret_requires_pac_ret: Warning< + "ignoring '-mharden-pac-ret' as it requires return address signing">, InGroup; def err_sls_hardening_arm_not_supported : Error< "-mharden-sls is only supported on armv7-a or later">; def warn_drv_large_data_threshold_invalid_code_model: Warning< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5cbbc7d130c99..fdfe7792441b9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3384,6 +3384,11 @@ def err_invalid_branch_protection_spec : Error< "invalid or misplaced branch protection specification '%0'">; def warn_unsupported_branch_protection_spec : Warning< "unsupported branch protection specification '%0'">, InGroup; +def warn_attribute_harden_pac_ret_requires_pac_ret: Warning< + "'harden-pac-ret' attribute requires 'branch-protection=pac-ret'; 'target' attribute ignored">, + InGroup; +def err_invalid_harden_pac_ret_spec : Error< + "invalid or misplaced pac-ret hardening specification '%0'">; def err_attribute_invalid_atomic_argument : Error< "invalid argument '%0' to atomic attribute; valid options are: " "'remote_memory', 'fine_grained_memory', 'ignore_denormal_mode' (optionally " diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 8cba1dbaee24e..f3c5613d3dab7 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -454,6 +454,8 @@ ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAd "Scope of return address signing") ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddressKeyKind::AKey, NotCompatible, "Key used for return address signing") +ENUM_LANGOPT(SignReturnAddressHardening, SignReturnAddressHardeningKind, 1, +
[clang] [llvm] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening (PR #176171)
https://github.com/vhscampos updated https://github.com/llvm/llvm-project/pull/176171 >From 4f775ae42fbc2729697b32ed5b5310a86f9cbfc4 Mon Sep 17 00:00:00 2001 From: Victor Campos Date: Tue, 13 Jan 2026 20:39:02 + Subject: [PATCH 1/4] [Clang][AArch64] Command-line options for A-profile's Sign Return Address Hardening This patch introduces a new command-line option to enable the AArch64 A-profile's Sign Return Address Hardening. It also introduces a new function attribute with the same naming as the new command-line option. At the time of this patch, this new option enables the hardening against the PACMAN attack [1] using a load of the return address [2]. The new option, -mharden-pac-ret, can take one of two values: - none: disable hardening. (The default if the option is absent) - load-return-address: enables hardening using the mitigation based on load of return address. The corresponding function attribute takes the option and its possible values using the same naming. 1: https://pacmanattack.com 2: https://developer.arm.com/documentation/101754/0624/armclang-Reference/armclang-Command-line-Options/-mharden-pac-ret --- .../clang/Basic/DiagnosticDriverKinds.td | 2 + .../clang/Basic/DiagnosticSemaKinds.td| 5 +++ clang/include/clang/Basic/LangOptions.def | 2 + clang/include/clang/Basic/LangOptions.h | 12 ++ clang/include/clang/Basic/TargetInfo.h| 22 ++ clang/include/clang/Options/Options.td| 9 clang/lib/Basic/Targets/AArch64.cpp | 16 +++ clang/lib/Basic/Targets/AArch64.h | 2 + clang/lib/CodeGen/TargetInfo.cpp | 4 ++ clang/lib/CodeGen/Targets/AArch64.cpp | 3 ++ clang/lib/Driver/ToolChains/Clang.cpp | 22 +- clang/lib/Sema/SemaDeclAttr.cpp | 18 +++- .../aarch64-sign-return-address-harden.c | 13 ++ clang/test/Driver/aarch64-security-options.c | 30 + clang/test/Driver/arm-security-options.c | 19 .../Frontend/aarch64-harden-pac-ret-err.c | 3 ++ .../aarch64-harden-pac-ret-attr-err-warn.c| 21 + clang/test/Sema/aarch64-harden-pac-ret-attr.c | 43 +++ 18 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 clang/test/CodeGen/aarch64-sign-return-address-harden.c create mode 100644 clang/test/Frontend/aarch64-harden-pac-ret-err.c create mode 100644 clang/test/Sema/aarch64-harden-pac-ret-attr-err-warn.c create mode 100644 clang/test/Sema/aarch64-harden-pac-ret-attr.c diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index db0f521b73544..d16fbd45f104e 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -544,6 +544,8 @@ def warn_ignoring_verify_debuginfo_preserve_export : Warning< InGroup; def warn_unsupported_branch_protection: Warning < "invalid branch protection option '%0' in '%1'">, InGroup; +def warn_harden_pac_ret_requires_pac_ret: Warning< + "ignoring '-mharden-pac-ret' as it requires return address signing">, InGroup; def err_sls_hardening_arm_not_supported : Error< "-mharden-sls is only supported on armv7-a or later">; def warn_drv_large_data_threshold_invalid_code_model: Warning< diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5cbbc7d130c99..fdfe7792441b9 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3384,6 +3384,11 @@ def err_invalid_branch_protection_spec : Error< "invalid or misplaced branch protection specification '%0'">; def warn_unsupported_branch_protection_spec : Warning< "unsupported branch protection specification '%0'">, InGroup; +def warn_attribute_harden_pac_ret_requires_pac_ret: Warning< + "'harden-pac-ret' attribute requires 'branch-protection=pac-ret'; 'target' attribute ignored">, + InGroup; +def err_invalid_harden_pac_ret_spec : Error< + "invalid or misplaced pac-ret hardening specification '%0'">; def err_attribute_invalid_atomic_argument : Error< "invalid argument '%0' to atomic attribute; valid options are: " "'remote_memory', 'fine_grained_memory', 'ignore_denormal_mode' (optionally " diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 8cba1dbaee24e..f3c5613d3dab7 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -454,6 +454,8 @@ ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAd "Scope of return address signing") ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddressKeyKind::AKey, NotCompatible, "Key used for return address signing") +ENUM_LANGOPT(SignReturnAddressHardening, SignReturnAddressHardeningKind, 1, +
