From 0ac44c18b7682c82aa7575b5c14cda0bbee798ad Mon Sep 17 00:00:00 2001 From: Luke Cheeseman Date: Fri, 17 Aug 2018 12:55:05 +0000 Subject: [PATCH] [AArch64] - return address signing - Add a command line options -msign-return-address to enable return address signing - Armv8.3a added instructions to sign the return address to help mitigate against ROP attacks - This patch adds command line options to generate function attributes that signal to the back whether return address signing instructions should be added Differential revision: https://reviews.llvm.org/D49793 llvm-svn: 340019 --- clang/include/clang/Driver/Options.td | 4 ++++ clang/include/clang/Frontend/CodeGenOptions.def | 1 + clang/include/clang/Frontend/CodeGenOptions.h | 6 ++++++ clang/lib/CodeGen/TargetInfo.cpp | 17 +++++++++++++++++ clang/lib/Driver/ToolChains/Clang.cpp | 5 +++++ clang/lib/Frontend/CompilerInvocation.cpp | 14 ++++++++++++++ clang/test/CodeGen/aarch64-sign-return-address.c | 14 ++++++++++++++ 7 files changed, 61 insertions(+) create mode 100644 clang/test/CodeGen/aarch64-sign-return-address.c diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 1878184..40d3d21 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -2030,6 +2030,10 @@ def ffixed_x18 : Flag<["-"], "ffixed-x18">, Group, def ffixed_x20 : Flag<["-"], "ffixed-x20">, Group, HelpText<"Reserve the x20 register (AArch64 only)">; +def msign_return_address : Joined<["-"], "msign-return-address=">, + Flags<[CC1Option]>, Group, + HelpText<"Select return address signing scope">, Values<"none,all,non-leaf">; + def msimd128 : Flag<["-"], "msimd128">, Group; def mno_simd128 : Flag<["-"], "mno-simd128">, Group; def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group; diff --git a/clang/include/clang/Frontend/CodeGenOptions.def b/clang/include/clang/Frontend/CodeGenOptions.def index a7e71f7..02997d9 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.def +++ b/clang/include/clang/Frontend/CodeGenOptions.def @@ -339,6 +339,7 @@ CODEGENOPT(ForceEmitVTables, 1, 0) /// Whether to emit an address-significance table into the object file. CODEGENOPT(Addrsig, 1, 0) +ENUM_CODEGENOPT(SignReturnAddress, SignReturnAddressScope, 2, None) #undef CODEGENOPT #undef ENUM_CODEGENOPT diff --git a/clang/include/clang/Frontend/CodeGenOptions.h b/clang/include/clang/Frontend/CodeGenOptions.h index a6d061a..d876344 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.h +++ b/clang/include/clang/Frontend/CodeGenOptions.h @@ -108,6 +108,12 @@ public: Embed_Marker // Embed a marker as a placeholder for bitcode. }; + enum SignReturnAddressScope { + None, // No signing for any function + NonLeaf, // Sign the return address of functions that spill LR + All // Sign the return address of all functions + }; + /// The code model to use (-mcmodel). std::string CodeModel; diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 6f6c5f5..9ad9674 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -4969,6 +4969,23 @@ public: } bool doesReturnSlotInterfereWithArgs() const override { return false; } + + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const override { + const FunctionDecl *FD = dyn_cast_or_null(D); + if (!FD) + return; + llvm::Function *Fn = cast(GV); + + auto Kind = CGM.getCodeGenOpts().getSignReturnAddress(); + if (Kind == CodeGenOptions::SignReturnAddressScope::None) + return; + + Fn->addFnAttr("sign-return-address", + Kind == CodeGenOptions::SignReturnAddressScope::All + ? "all" + : "non-leaf"); + } }; class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 98ca6b6..66b9082 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1455,6 +1455,11 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, else CmdArgs.push_back("-aarch64-enable-global-merge=true"); } + + if (Arg *A = Args.getLastArg(options::OPT_msign_return_address)) { + CmdArgs.push_back( + Args.MakeArgString(Twine("-msign-return-address=") + A->getValue())); + } } void Clang::AddMIPSTargetArgs(const ArgList &Args, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index ed22c1a..c93ff2a 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1125,6 +1125,20 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.Addrsig = Args.hasArg(OPT_faddrsig); + if (Arg *A = Args.getLastArg(OPT_msign_return_address)) { + StringRef SignScope = A->getValue(); + if (SignScope.equals_lower("none")) + Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::None); + else if (SignScope.equals_lower("all")) + Opts.setSignReturnAddress(CodeGenOptions::SignReturnAddressScope::All); + else if (SignScope.equals_lower("non-leaf")) + Opts.setSignReturnAddress( + CodeGenOptions::SignReturnAddressScope::NonLeaf); + else + Diags.Report(diag::err_drv_invalid_value) + << A->getAsString(Args) << A->getValue(); + } + return Success; } diff --git a/clang/test/CodeGen/aarch64-sign-return-address.c b/clang/test/CodeGen/aarch64-sign-return-address.c new file mode 100644 index 0000000..d656bc3 --- /dev/null +++ b/clang/test/CodeGen/aarch64-sign-return-address.c @@ -0,0 +1,14 @@ +// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=none %s | FileCheck %s --check-prefix=CHECK-NONE +// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=non-leaf %s | FileCheck %s --check-prefix=CHECK-PARTIAL +// RUN: %clang -target aarch64-arm-none-eabi -S -emit-llvm -o - -msign-return-address=all %s | FileCheck %s --check-prefix=CHECK-ALL + +// CHECK-NONE: @foo() #[[ATTR:[0-9]*]] +// CHECK-NONE-NOT: attributes #[[ATTR]] = { {{.*}} "sign-return-address"={{.*}} }} + +// CHECK-PARTIAL: @foo() #[[ATTR:[0-9]*]] +// CHECK-PARTIAL: attributes #[[ATTR]] = { {{.*}} "sign-return-address"="non-leaf" {{.*}}} + +// CHECK-ALL: @foo() #[[ATTR:[0-9]*]] +// CHECK-ALL: attributes #[[ATTR]] = { {{.*}} "sign-return-address"="all" {{.*}} } + +void foo() {} -- 2.7.4