llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Roland McGrath (frobtech) <details> <summary>Changes</summary> Enable branch target protection by default for 64-bit Fuchsia targets. On AArch64, pass -mbranch-target-enforce by default (and keep it enabled when -msign-return-address= is used alone); 32-bit ARM (armv8-a) is unchanged as A-profile AArch32 has no BTI support. On RISC-V (Zicfilp lpad), pass -fcf-protection=branch by default when no -fcf-protection= option is given. On x86-64 (IBT), pass -fcf-protection=branch and -fno-jump-tables by default when no -fcf-protection= option is given, avoiding `notrack` indirect jumps as the preferred security choice. Increment __Fuchsia_Compiler_ABI__ from 1 to 2 so that Fuchsia code can rely on branch target protection being enabled by default across all supported architectures. Assisted-by: Gemini --- Full diff: https://github.com/llvm/llvm-project/pull/236000.diff 5 Files Affected: - (modified) clang/lib/Basic/Targets/OSTargets.cpp (+11-1) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+31-11) - (modified) clang/test/Driver/aarch64-security-options.c (+12) - (modified) clang/test/Driver/fuchsia.c (+36-8) - (modified) clang/test/Preprocessor/init-fuchsia.c (+1-1) ``````````diff diff --git a/clang/lib/Basic/Targets/OSTargets.cpp b/clang/lib/Basic/Targets/OSTargets.cpp index 04d9e13d3c9a6..63be4239fe6ff 100644 --- a/clang/lib/Basic/Targets/OSTargets.cpp +++ b/clang/lib/Basic/Targets/OSTargets.cpp @@ -322,9 +322,19 @@ void getFuchsiaDefines(MacroBuilder &Builder, const LangOptions &Opts, // * Version 1 is first iteration formalizing the version number scheme. // - SafeStack ABI no longer supported on aarch64, riscv64 (x86 only) // + // * Version 2 is entirely backward-compatible with version 1, but also + // adds new guarantees that can be presumed of all ABI-compatible code. + // - aarch64 BTI support (-mbranch-protection=bti) is on by default. + // (32-bit armv8-a has no BTI support; 32-bit BTI only exists in M-profile + // armv8.1-m.main and is not backward-compatible with armv8-a.) + // - RISC-V lpad support (-fcf-protection=branch) is on by default. + // - x86-64 IBT support (-fcf-protection=branch) is on by default, with + // jump tables disabled (-fno-jump-tables) to avoid `notrack` indirect + // jumps as the preferred security choice. + // // The predefine can be checked by code relying on the Fuchsia Compiler ABI // to ensure that a compiler new enough for the required version is in use. - Builder.defineMacro("__Fuchsia_Compiler_ABI__", Twine(1)); + Builder.defineMacro("__Fuchsia_Compiler_ABI__", Twine(2)); } } // namespace targets diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 5a1c8531812bd..0efb2a89e4cc0 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1401,6 +1401,14 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, : Args.getLastArg(options::OPT_mbranch_protection_EQ); const Arg *HardenPACRetArg = Args.getLastArg(options::OPT_mharden_pac_ret_EQ); const Driver &D = TC.getDriver(); + // Fuchsia (like Android and OpenBSD) enables BTI by default only on AArch64; + // 32-bit Armv8-A is not compatible with BTI (which in 32-bit ARM only exists + // on Armv8.1-M M-profile). + const bool DefaultIndirectBranches = + (Triple.isOSOpenBSD() || Triple.isAndroid() || Triple.isOSFuchsia()) && + isAArch64; + const bool DefaultPACNonLeafKeyA = + (Triple.isOSOpenBSD() || Triple.isAndroid()) && isAArch64; if (HardenPACRetArg) { if (!isAArch64) { @@ -1441,14 +1449,13 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, }; if (!A) { - if ((Triple.isOSOpenBSD() || Triple.isAndroid()) && isAArch64) { + if (DefaultPACNonLeafKeyA) { CmdArgs.push_back("-msign-return-address=non-leaf"); CmdArgs.push_back("-msign-return-address-key=a_key"); - CmdArgs.push_back("-mbranch-target-enforce"); - RenderHardenPACRet("non-leaf"); - } else { - RenderHardenPACRet("none"); } + if (DefaultIndirectBranches) + CmdArgs.push_back("-mbranch-target-enforce"); + RenderHardenPACRet(DefaultPACNonLeafKeyA ? "non-leaf" : "none"); return; } @@ -1467,8 +1474,7 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, // This spelling cannot express a key, and AArch64 Windows and UEFI only // support B-key, so default to it there as parseBranchProtection() does. Key = isAArch64 && Triple.isOSWindowsOrUEFI() ? "b_key" : "a_key"; - IndirectBranches = - (Triple.isOSOpenBSD() || Triple.isAndroid()) && isAArch64; + IndirectBranches = DefaultIndirectBranches; BranchProtectionPAuthLR = false; GuardedControlStack = false; } else { @@ -7513,6 +7519,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (!Args.hasFlag(options::OPT_offloadlib, options::OPT_no_offloadlib, true)) CmdArgs.push_back("--no-offloadlib"); + const bool DefaultCfProtectionBranch = + (Triple.getArch() == llvm::Triple::x86_64 && + (Triple.isOSOpenBSD() || Triple.isOSFuchsia())) || + (Triple.getArch() == llvm::Triple::riscv64 && Triple.isOSFuchsia()); + // On x86-64 with -fcf-protection=branch, jump tables emit `notrack jmp` + // rather than `endbr64` on target blocks. Targets that avoid `notrack` (so + // CET can disallow `notrack` indirect branches) disable jump tables by + // default when branch protection is enabled. For OpenBSD and Fuchsia on + // x86-64, avoiding `notrack` is the preferred security choice. + const bool DefaultX86NoTrackAvoided = + Triple.getArch() == llvm::Triple::x86_64 && + (Triple.isOSOpenBSD() || Triple.isOSFuchsia()); + if (Arg *A = Args.getLastArg(options::OPT_fcf_protection_EQ)) { CmdArgs.push_back( Args.MakeArgString(Twine("-fcf-protection=") + A->getValue())); @@ -7520,11 +7539,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (Arg *SA = Args.getLastArg(options::OPT_mcf_branch_label_scheme_EQ)) CmdArgs.push_back(Args.MakeArgString(Twine("-mcf-branch-label-scheme=") + SA->getValue())); - } else if (Triple.isOSOpenBSD() && Triple.getArch() == llvm::Triple::x86_64) { - // Emit IBT endbr64 instructions by default + } else if (DefaultCfProtectionBranch) { + // Emit IBT endbr64 / Zicfilp lpad instructions by default. CmdArgs.push_back("-fcf-protection=branch"); - // jump-table can generate indirect jumps, which are not permitted - CmdArgs.push_back("-fno-jump-tables"); + if (DefaultX86NoTrackAvoided && + !Args.hasArg(options::OPT_fjump_tables, options::OPT_fno_jump_tables)) + CmdArgs.push_back("-fno-jump-tables"); } if (Arg *A = Args.getLastArg(options::OPT_mfunction_return_EQ)) diff --git a/clang/test/Driver/aarch64-security-options.c b/clang/test/Driver/aarch64-security-options.c index 81a7d7c571542..9df5b24c66604 100644 --- a/clang/test/Driver/aarch64-security-options.c +++ b/clang/test/Driver/aarch64-security-options.c @@ -65,6 +65,18 @@ // RUN: %clang --target=aarch64-linux-android -msign-return-address=non-leaf -### -c %s 2>&1 | \ // RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-ON --check-prefix=GCS-OFF --check-prefix=WARN +// Check that Fuchsia enables BTI by default on AArch64. +// RUN: %clang --target=aarch64-unknown-fuchsia -### -c %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=BTE-ON --check-prefix=GCS-OFF --check-prefix=WARN + +// Check that the Fuchsia default can be overridden. +// RUN: %clang --target=aarch64-unknown-fuchsia -mbranch-protection=none -### -c %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=RA-OFF --check-prefix=KEY --check-prefix=BTE-OFF --check-prefix=GCS-OFF --check-prefix=WARN + +// Check that Fuchsia enables BTI by default when -msign-return-address is passed. +// RUN: %clang --target=aarch64-unknown-fuchsia -msign-return-address=non-leaf -### -c %s 2>&1 | \ +// RUN: FileCheck %s --check-prefix=RA-NON-LEAF --check-prefix=KEY-A --check-prefix=BTE-ON --check-prefix=GCS-OFF --check-prefix=WARN + // 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 | \ diff --git a/clang/test/Driver/fuchsia.c b/clang/test/Driver/fuchsia.c index 10135b204ffff..a80e843d71190 100644 --- a/clang/test/Driver/fuchsia.c +++ b/clang/test/Driver/fuchsia.c @@ -1,45 +1,73 @@ // RUN: %clang -### %s --target=x86_64-unknown-fuchsia \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHECK,CHECK-X86_64 %s +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-X86_64,CHECK-CF-PROT,CHECK-DEF-NO-JT %s // RUN: %clang -### %s --target=arm-unknown-fuchsia \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARMV8A %s +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARMV8A,CHECK-ARM-NOBTI,CHECK-JT %s // RUN: %clang -### %s --target=aarch64-unknown-fuchsia \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHECK,CHECK-AARCH64 %s +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-AARCH64,CHECK-ARM-BTI,CHECK-JT %s // RUN: %clang -### %s --target=riscv64-unknown-fuchsia \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHECK,CHECK-RISCV64 %s +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-RISCV64,CHECK-CF-PROT,CHECK-JT %s // RUN: %clang -### %s --target=x86_64-fuchsia \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHECK,CHECK-X86_64 %s +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-X86_64,CHECK-CF-PROT,CHECK-DEF-NO-JT %s +// RUN: %clang -### %s --target=x86_64-fuchsia -fjump-tables \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-X86_64,CHECK-CF-PROT,CHECK-JT %s +// RUN: %clang -### %s --target=x86_64-fuchsia -fcf-protection=none \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-X86_64,CHECK-CF-NOPROT,CHECK-JT %s +// RUN: %clang -### %s --target=x86_64-fuchsia -fcf-protection=none -fno-jump-tables \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-X86_64,CHECK-CF-NOPROT,CHECK-EXPL-NO-JT %s // RUN: %clang -### %s --target=arm-fuchsia \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARMV8A %s +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-ARMV8A,CHECK-ARM-NOBTI,CHECK-JT %s // RUN: %clang -### %s --target=aarch64-fuchsia \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHECK,CHECK-AARCH64 %s +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-AARCH64,CHECK-ARM-BTI,CHECK-JT %s +// RUN: %clang -### %s --target=aarch64-fuchsia -mbranch-protection=none \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-AARCH64,CHECK-ARM-NOBTI,CHECK-JT %s // RUN: %clang -### %s --target=riscv64-fuchsia \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ -// RUN: | FileCheck -check-prefixes=CHECK,CHECK-RISCV64 %s +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-RISCV64,CHECK-CF-PROT,CHECK-JT %s +// RUN: %clang -### %s --target=riscv64-fuchsia -fcf-protection=none \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: --sysroot=%S/platform -fuse-ld=ld 2>&1 \ +// RUN: | FileCheck -check-prefixes=CHECK,CHECK-RISCV64,CHECK-CF-NOPROT,CHECK-JT %s // CHECK: "-cc1" // CHECK-X86_64: "-triple" "x86_64-unknown-fuchsia" // CHECK-ARMV8A: "-triple" "thumbv8a-unknown-fuchsia" // CHECK-AARCH64: "-triple" "aarch64-unknown-fuchsia" // CHECK-RISCV64: "-triple" "riscv64-unknown-fuchsia" +// CHECK-EXPL-NO-JT: "-fno-jump-tables" +// CHECK-JT-NOT: "-fno-jump-tables" // CHECK: "-funwind-tables=2" +// CHECK-ARM-BTI: "-mbranch-target-enforce" +// CHECK-ARM-NOBTI-NOT: "-mbranch-target-enforce" // CHECK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK: "-isysroot" "[[SYSROOT:[^"]+]]" // CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include" // CHECK: "-stack-protector" "2" +// CHECK-CF-PROT: "-fcf-protection=branch" +// CHECK-CF-NOPROT: "-fcf-protection=none" +// CHECK-DEF-NO-JT: "-fno-jump-tables" +// CHECK-JT-NOT: "-fno-jump-tables" // CHECK-AARCH64: "-fsanitize=shadow-call-stack" // CHECK-RISCV64: "-fsanitize=shadow-call-stack" // CHECK-X86_64: "-fsanitize=safe-stack" diff --git a/clang/test/Preprocessor/init-fuchsia.c b/clang/test/Preprocessor/init-fuchsia.c index 04b5ef573cc07..c45742c868f12 100644 --- a/clang/test/Preprocessor/init-fuchsia.c +++ b/clang/test/Preprocessor/init-fuchsia.c @@ -9,4 +9,4 @@ // FUCHSIA-DAG: #define __Fuchsia__ 1 // FUCHSIA-DAG: #define __Fuchsia_API_level__ {{[0-9]+}} -// FUCHSIA-DAG: #define __Fuchsia_Compiler_ABI__ 1 +// FUCHSIA-DAG: #define __Fuchsia_Compiler_ABI__ 2 `````````` </details> https://github.com/llvm/llvm-project/pull/236000 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
