Skip to content

Commit cf50a84

Browse files
authored
[PAC] Authenticate function pointers in UBSan type checks (#99590)
The function pointer needs to be authenticated before doing the type checks.
1 parent ac11430 commit cf50a84

File tree

4 files changed

+20
-1
lines changed

4 files changed

+20
-1
lines changed

clang/lib/CodeGen/Address.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,9 @@ class Address {
249249
/// Return the pointer contained in this class after authenticating it and
250250
/// adding offset to it if necessary.
251251
llvm::Value *emitRawPointer(CodeGenFunction &CGF) const {
252-
return getBasePointer();
252+
if (!isSigned())
253+
return getBasePointer();
254+
return emitRawPointerSlow(CGF);
253255
}
254256

255257
/// Return address with different pointer, but same element type and

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5837,6 +5837,15 @@ RValue CodeGenFunction::EmitCall(QualType CalleeType, const CGCallee &OrigCallee
58375837
CGM.getLLVMContext(), {PrefixSigType, Int32Ty}, /*isPacked=*/true);
58385838

58395839
llvm::Value *CalleePtr = Callee.getFunctionPointer();
5840+
if (CGM.getCodeGenOpts().PointerAuth.FunctionPointers) {
5841+
// Use raw pointer since we are using the callee pointer as data here.
5842+
Address Addr =
5843+
Address(CalleePtr, CalleePtr->getType(),
5844+
CharUnits::fromQuantity(
5845+
CalleePtr->getPointerAlignment(CGM.getDataLayout())),
5846+
Callee.getPointerAuthInfo(), nullptr);
5847+
CalleePtr = Addr.emitRawPointer(*this);
5848+
}
58405849

58415850
// On 32-bit Arm, the low bit of a function pointer indicates whether
58425851
// it's using the Arm or Thumb instruction set. The actual first

clang/lib/CodeGen/CGPointerAuth.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,10 @@ Address Address::getResignedAddress(const CGPointerAuthInfo &NewInfo,
566566
/*Offset=*/nullptr, isKnownNonNull());
567567
}
568568

569+
llvm::Value *Address::emitRawPointerSlow(CodeGenFunction &CGF) const {
570+
return CGF.getAsNaturalPointerTo(*this, QualType());
571+
}
572+
569573
llvm::Value *LValue::getPointer(CodeGenFunction &CGF) const {
570574
assert(isSimple());
571575
return emitResignedPointer(getType(), CGF);

clang/test/CodeGen/ubsan-function.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
// 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
55
// 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
66

7+
// 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
8+
79
// GNU: define{{.*}} void @_Z3funv() #0 !func_sanitize ![[FUNCSAN:.*]] {
810
// MSVC: define{{.*}} void @"?fun@@YAXXZ"() #0 !func_sanitize ![[FUNCSAN:.*]] {
911
void fun() {}
@@ -13,6 +15,8 @@ void fun() {}
1315
// ARM: ptrtoint ptr {{.*}} to i32, !nosanitize !5
1416
// ARM: and i32 {{.*}}, -2, !nosanitize !5
1517
// ARM: inttoptr i32 {{.*}} to ptr, !nosanitize !5
18+
// 64e: %[[STRIPPED:.*]] = ptrtoint ptr {{.*}} to i64, !nosanitize
19+
// 64e: call i64 @llvm.ptrauth.auth(i64 %[[STRIPPED]], i32 0, i64 0), !nosanitize
1620
// CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 0, !nosanitize
1721
// CHECK: load i32, ptr {{.*}}, align {{.*}}, !nosanitize
1822
// CHECK: icmp eq i32 {{.*}}, -1056584962, !nosanitize

0 commit comments

Comments
 (0)