Skip to content

Commit

Permalink
[AArch64] - return address signing
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
Luke Cheeseman committed Aug 17, 2018
1 parent 64dcdec commit 0ac44c1
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 0 deletions.
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Expand Up @@ -2030,6 +2030,10 @@ def ffixed_x18 : Flag<["-"], "ffixed-x18">, Group<m_aarch64_Features_Group>,
def ffixed_x20 : Flag<["-"], "ffixed-x20">, Group<m_aarch64_Features_Group>,
HelpText<"Reserve the x20 register (AArch64 only)">;

def msign_return_address : Joined<["-"], "msign-return-address=">,
Flags<[CC1Option]>, Group<m_Group>,
HelpText<"Select return address signing scope">, Values<"none,all,non-leaf">;

def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>;
def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>;
def mnontrapping_fptoint : Flag<["-"], "mnontrapping-fptoint">, Group<m_wasm_Features_Group>;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Frontend/CodeGenOptions.def
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Frontend/CodeGenOptions.h
Expand Up @@ -108,6 +108,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
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;

Expand Down
17 changes: 17 additions & 0 deletions clang/lib/CodeGen/TargetInfo.cpp
Expand Up @@ -4969,6 +4969,23 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
}

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<FunctionDecl>(D);
if (!FD)
return;
llvm::Function *Fn = cast<llvm::Function>(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 {
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Expand Up @@ -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,
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Expand Up @@ -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;
}

Expand Down
14 changes: 14 additions & 0 deletions 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() {}

0 comments on commit 0ac44c1

Please sign in to comment.