Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PAC] Authenticate function pointers in UBSan type checks #99590

Merged
merged 1 commit into from
Jul 19, 2024

Conversation

ahatanak
Copy link
Collaborator

The function pointer needs to be authenticated before doing the type checks.

The function pointer needs to be authenticated before doing the type
checks.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:codegen labels Jul 19, 2024
@llvmbot
Copy link
Member

llvmbot commented Jul 19, 2024

@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-clang

Author: Akira Hatanaka (ahatanak)

Changes

The function pointer needs to be authenticated before doing the type checks.


Full diff: https://github.com/llvm/llvm-project/pull/99590.diff

4 Files Affected:

  • (modified) clang/lib/CodeGen/Address.h (+3-1)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+9)
  • (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+4)
  • (modified) clang/test/CodeGen/ubsan-function.cpp (+4)
diff --git a/clang/lib/CodeGen/Address.h b/clang/lib/CodeGen/Address.h
index 1c4d2e103b5e7..a18c7169af1eb 100644
--- a/clang/lib/CodeGen/Address.h
+++ b/clang/lib/CodeGen/Address.h
@@ -249,7 +249,9 @@ class Address {
   /// Return the pointer contained in this class after authenticating it and
   /// adding offset to it if necessary.
   llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
-    return getBasePointer();
+    if (!isSigned())
+      return getBasePointer();
+    return emitRawPointerSlow(CGF);
   }
 
   /// Return address with different pointer, but same element type and
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index c5341e4b53651..aa53f96358044 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5837,6 +5837,15 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
           CGM.getLLVMContext(), {PrefixSigType, Int32Ty}, /*isPacked=*/true);
 
       llvm::Value *CalleePtr = Callee.getFunctionPointer();
+      if (CGM.getCodeGenOpts().PointerAuth.FunctionPointers) {
+        // Use raw pointer since we are using the callee pointer as data here.
+        Address Addr =
+            Address(CalleePtr, CalleePtr->getType(),
+                    CharUnits::fromQuantity(
+                        CalleePtr->getPointerAlignment(CGM.getDataLayout())),
+                    Callee.getPointerAuthInfo(), nullptr);
+        CalleePtr = Addr.emitRawPointer(*this);
+      }
 
       // On 32-bit Arm, the low bit of a function pointer indicates whether
       // it's using the Arm or Thumb instruction set. The actual first
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp
index 7fe62c0788742..72aed9f24d595 100644
--- a/clang/lib/CodeGen/CGPointerAuth.cpp
+++ b/clang/lib/CodeGen/CGPointerAuth.cpp
@@ -566,6 +566,10 @@ Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo,
                  /*Offset=*/nullptr, isKnownNonNull());
 }
 
+llvm::Value *Address::emitRawPointerSlow(CodeGenFunction &CGF) const {
+  return CGF.getAsNaturalPointerTo(*this, QualType());
+}
+
 llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const {
   assert(isSimple());
   return emitResignedPointer(getType(), CGF);
diff --git a/clang/test/CodeGen/ubsan-function.cpp b/clang/test/CodeGen/ubsan-function.cpp
index bc37a61c98ee3..8478f05a10b78 100644
--- a/clang/test/CodeGen/ubsan-function.cpp
+++ b/clang/test/CodeGen/ubsan-function.cpp
@@ -4,6 +4,8 @@
 // RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefixes=CHECK,GNU,64
 // RUN: %clang_cc1 -triple arm-none-eabi -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefixes=CHECK,ARM,GNU,32
 
+// RUN: %clang_cc1 -triple arm64e-apple-ios -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all -fptrauth-calls | FileCheck %s --check-prefixes=CHECK,GNU,64,64e
+
 // GNU:  define{{.*}} void @_Z3funv() #0 !func_sanitize ![[FUNCSAN:.*]] {
 // MSVC: define{{.*}} void @"?fun@@YAXXZ"() #0 !func_sanitize ![[FUNCSAN:.*]] {
 void fun() {}
@@ -13,6 +15,8 @@ void fun() {}
 // ARM:   ptrtoint ptr {{.*}} to i32, !nosanitize !5
 // ARM:   and i32 {{.*}}, -2, !nosanitize !5
 // ARM:   inttoptr i32 {{.*}} to ptr, !nosanitize !5
+// 64e:   %[[STRIPPED:.*]] = ptrtoint ptr {{.*}} to i64, !nosanitize
+// 64e:   call i64 @llvm.ptrauth.auth(i64 %[[STRIPPED]], i32 0, i64 0), !nosanitize
 // CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 0, !nosanitize
 // CHECK: load i32, ptr {{.*}}, align {{.*}}, !nosanitize
 // CHECK: icmp eq i32 {{.*}}, -1056584962, !nosanitize

@@ -13,6 +15,8 @@ void fun() {}
// ARM: ptrtoint ptr {{.*}} to i32, !nosanitize !5
// ARM: and i32 {{.*}}, -2, !nosanitize !5
// ARM: inttoptr i32 {{.*}} to ptr, !nosanitize !5
// 64e: %[[STRIPPED:.*]] = ptrtoint ptr {{.*}} to i64, !nosanitize
// 64e: call i64 @llvm.ptrauth.auth(i64 %[[STRIPPED]], i32 0, i64 0), !nosanitize
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sadly we are not checking full sequence here :( But this is not a problem of this patch, it is just underlying test done this way

@ahatanak ahatanak merged commit cf50a84 into llvm:main Jul 19, 2024
10 checks passed
@ahatanak ahatanak deleted the auth-fp-ubsan branch July 19, 2024 15:27
sgundapa pushed a commit to sgundapa/upstream_effort that referenced this pull request Jul 23, 2024
The function pointer needs to be authenticated before doing the type
checks.
kovdan01 added a commit to kovdan01/llvm-project that referenced this pull request Jul 23, 2024
Implement tests for the following PAuth-related features:

- driver, preprocessor and ELF codegen tests for type_info vtable
  pointer discrimination llvm#99726;

- driver, preprocessor, and ELF codegen (emitting function attributes) +
  sema (emitting errors) tests for indirect gotos signing llvm#97647;

- ELF codegen tests for ubsan type checks + auth llvm#99590;

- ELF codegen tests for constant global init with polymorphic MI llvm#99741;

- ELF codegen tests for C++ member function pointers auth llvm#99576.
kovdan01 added a commit that referenced this pull request Jul 24, 2024
…100206)

Implement tests for the following PAuth-related features:

- driver, preprocessor and ELF codegen tests for type_info vtable
pointer discrimination #99726;

- driver, preprocessor, and ELF codegen (emitting function attributes) +
sema (emitting errors) tests for indirect gotos signing #97647;

- ELF codegen tests for ubsan type checks + auth #99590;

- ELF codegen tests for constant global init with polymorphic MI #99741;

- ELF codegen tests for C++ member function pointers auth #99576.
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
Summary:
The function pointer needs to be authenticated before doing the type
checks.

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60251193
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
…100206)

Summary:
Implement tests for the following PAuth-related features:

- driver, preprocessor and ELF codegen tests for type_info vtable
pointer discrimination #99726;

- driver, preprocessor, and ELF codegen (emitting function attributes) +
sema (emitting errors) tests for indirect gotos signing #97647;

- ELF codegen tests for ubsan type checks + auth #99590;

- ELF codegen tests for constant global init with polymorphic MI #99741;

- ELF codegen tests for C++ member function pointers auth #99576.

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60250599
llvmbot pushed a commit to llvmbot/llvm-project that referenced this pull request Jul 29, 2024
…lvm#100206)

Implement tests for the following PAuth-related features:

- driver, preprocessor and ELF codegen tests for type_info vtable
pointer discrimination llvm#99726;

- driver, preprocessor, and ELF codegen (emitting function attributes) +
sema (emitting errors) tests for indirect gotos signing llvm#97647;

- ELF codegen tests for ubsan type checks + auth llvm#99590;

- ELF codegen tests for constant global init with polymorphic MI llvm#99741;

- ELF codegen tests for C++ member function pointers auth llvm#99576.

(cherry picked from commit 70c6e79)
tru pushed a commit to llvmbot/llvm-project that referenced this pull request Jul 30, 2024
…lvm#100206)

Implement tests for the following PAuth-related features:

- driver, preprocessor and ELF codegen tests for type_info vtable
pointer discrimination llvm#99726;

- driver, preprocessor, and ELF codegen (emitting function attributes) +
sema (emitting errors) tests for indirect gotos signing llvm#97647;

- ELF codegen tests for ubsan type checks + auth llvm#99590;

- ELF codegen tests for constant global init with polymorphic MI llvm#99741;

- ELF codegen tests for C++ member function pointers auth llvm#99576.

(cherry picked from commit 70c6e79)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:codegen clang Clang issues not falling into any other category
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants