From ccd8d0497a92c50e52933cd5d712a32a192ba6aa Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Fri, 9 Aug 2024 11:49:50 -0700 Subject: [PATCH] [clang] Wire -fptrauth-returns to "ptrauth-returns" fn attribute. (#102416) We already ended up with -fptrauth-returns, the feature macro, the lang opt, and the actual backend lowering. The only part left is threading it all through PointerAuthOptions, to drive the addition of the "ptrauth-returns" attribute to generated functions. While there, do minor cleanup on ptrauth-function-attributes.c. This also adds ptrauth_key_return_address to ptrauth.h. (cherry picked from commit 2eb6e30fe83ccce3cf01e596e73fa6385facd44b) --- clang/include/clang/Basic/PointerAuthOptions.h | 3 +++ clang/lib/CodeGen/CodeGenFunction.cpp | 2 ++ clang/lib/Frontend/CompilerInvocation.cpp | 4 +++- clang/lib/Headers/ptrauth.h | 6 ++++++ clang/test/CodeGen/ptrauth-function-attributes.c | 9 +++++++-- 5 files changed, 21 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Basic/PointerAuthOptions.h b/clang/include/clang/Basic/PointerAuthOptions.h index 417b4b00648c78..c0ab35bce5d84b 100644 --- a/clang/include/clang/Basic/PointerAuthOptions.h +++ b/clang/include/clang/Basic/PointerAuthOptions.h @@ -159,6 +159,9 @@ class PointerAuthSchema { }; struct PointerAuthOptions { + /// Should return addresses be authenticated? + bool ReturnAddresses = false; + /// Do indirect goto label addresses need to be authenticated? bool IndirectGotos = false; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index af201554898f31..4dc57d0ff5b269 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -880,6 +880,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // Add pointer authentication attributes. const CodeGenOptions &CodeGenOpts = CGM.getCodeGenOpts(); + if (CodeGenOpts.PointerAuth.ReturnAddresses) + Fn->addFnAttr("ptrauth-returns"); if (CodeGenOpts.PointerAuth.FunctionPointers) Fn->addFnAttr("ptrauth-calls"); if (CodeGenOpts.PointerAuth.IndirectGotos) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index f6b6c44a4cab6a..fa5d076c202a36 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1505,13 +1505,15 @@ void CompilerInvocation::setDefaultPointerAuthOptions( PointerAuthSchema(Key::ASIA, false, Discrimination::Type); } Opts.IndirectGotos = LangOpts.PointerAuthIndirectGotos; + Opts.ReturnAddresses = LangOpts.PointerAuthReturns; } static void parsePointerAuthOptions(PointerAuthOptions &Opts, const LangOptions &LangOpts, const llvm::Triple &Triple, DiagnosticsEngine &Diags) { - if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthIndirectGotos) + if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthIndirectGotos && + !LangOpts.PointerAuthReturns) return; CompilerInvocation::setDefaultPointerAuthOptions(Opts, LangOpts, Triple); diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h index 4724155b0dc796..154b599862a8e2 100644 --- a/clang/lib/Headers/ptrauth.h +++ b/clang/lib/Headers/ptrauth.h @@ -28,6 +28,12 @@ typedef enum { /* A process-specific key which can be used to sign data pointers. */ ptrauth_key_process_dependent_data = ptrauth_key_asdb, + /* The key used to sign return addresses on the stack. + The extra data is based on the storage address of the return address. + On AArch64, that is always the storage address of the return address + 8 + (or, in other words, the value of the stack pointer on function entry) */ + ptrauth_key_return_address = ptrauth_key_process_dependent_code, + /* The key used to sign C function pointers. The extra data is always 0. */ ptrauth_key_function_pointer = ptrauth_key_process_independent_code, diff --git a/clang/test/CodeGen/ptrauth-function-attributes.c b/clang/test/CodeGen/ptrauth-function-attributes.c index 6a09cd37bf4854..17ebf9d6e2e01c 100644 --- a/clang/test/CodeGen/ptrauth-function-attributes.c +++ b/clang/test/CodeGen/ptrauth-function-attributes.c @@ -1,11 +1,14 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,OFF // RUN: %clang_cc1 -triple arm64e-apple-ios -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,OFF // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,OFF -// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,CALLS +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,CALLS // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,CALLS +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-returns -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,RETS +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-returns -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,RETS + // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS -// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-indirect-gotos -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,GOTOS // ALL: define {{(dso_local )?}}void @test() #0 @@ -14,6 +17,8 @@ void test() { // CALLS: attributes #0 = {{{.*}} "ptrauth-calls" {{.*}}} +// RETS: attributes #0 = {{{.*}} "ptrauth-returns" {{.*}}} + // GOTOS: attributes #0 = {{{.*}} "ptrauth-indirect-gotos" {{.*}}} // OFF-NOT: attributes {{.*}} "ptrauth-