https://github.com/asl updated https://github.com/llvm/llvm-project/pull/140276

>From ed3d47d43571d734aa01e9b6dbaa237f653374da Mon Sep 17 00:00:00 2001
From: Anton Korobeynikov <[email protected]>
Date: Fri, 16 May 2025 19:25:57 +0300
Subject: [PATCH 1/2] [PAuth] Use different discriminators for __int128_t /
 __uint128_t / _BitInt(n) compared to other integer types when computing
 function pointer type discriminator.

These parameter types have different parameter passing ABI as compared to
ordinary integer types (e.g. require 2 registers instead of 1) and therefore
this parameter passing difference could potentially be exploited should function
pointer is substituted.
---
 clang/lib/AST/ASTContext.cpp                  | 14 ++++++---
 .../ptrauth-function-type-discriminator.c     | 31 +++++++++++++++++++
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a6eb87ab7d8aa..09d949b5e1643 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3506,21 +3506,27 @@ static void encodeTypeForFunctionPointerAuth(const 
ASTContext &Ctx,
 
   // Don't bother discriminating based on these types.
   case Type::Pipe:
-  case Type::BitInt:
   case Type::ConstantMatrix:
     OS << "?";
     return;
 
+  case Type::BitInt: {
+    const auto *BtTy = T->castAs<BitIntType>();
+    OS << "D" << (BtTy->isUnsigned() ? "U" : "B") << BtTy->getNumBits() << "_";
+    return;
+  }
+
   case Type::Builtin: {
     const auto *BTy = T->castAs<BuiltinType>();
-    switch (BTy->getKind()) {
+    const auto Kind = BTy->getKind();
+    switch (Kind) {
 #define SIGNED_TYPE(Id, SingletonId)                                           
\
   case BuiltinType::Id:                                                        
\
-    OS << "i";                                                                 
\
+    OS << (Kind == BuiltinType::Int128 ? "n" : "i");                           
\
     return;
 #define UNSIGNED_TYPE(Id, SingletonId)                                         
\
   case BuiltinType::Id:                                                        
\
-    OS << "i";                                                                 
\
+    OS << (Kind == BuiltinType::UInt128 ? "o" : "i");                          
\
     return;
 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
 #define BUILTIN_TYPE(Id, SingletonId)
diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator.c 
b/clang/test/CodeGen/ptrauth-function-type-discriminator.c
index 0952c1abf6c07..9bf4a8874c3c3 100644
--- a/clang/test/CodeGen/ptrauth-function-type-discriminator.c
+++ b/clang/test/CodeGen/ptrauth-function-type-discriminator.c
@@ -65,6 +65,37 @@ void (*fptr3)(void) = 
__builtin_ptrauth_sign_constant(&external_function, 2, 26)
 // CHECK: @fptr4 = global ptr ptrauth (ptr @external_function, i32 2, i64 26, 
ptr @fptr4)
 void (*fptr4)(void) = __builtin_ptrauth_sign_constant(&external_function, 2, 
__builtin_ptrauth_blend_discriminator(&fptr4, 26));
 
+extern void external_function_int(int);
+extern void external_function_char(char);
+extern void external_function_i128(__int128_t);
+extern void external_function_u128(__uint128_t);
+extern void external_function_b128(_BitInt(128));
+extern void external_function_b8(_BitInt(8));
+
+// Check discriminators of functions taking integer type arguments:
+
+//  - Builtin integer types should be discriminated equally (so, pointer to
+//  function taking int argument should accept function taking char argument
+//  - _BitInt types are guaranteed distinct and therefore should be 
discriminated
+//  differently
+//  - __int128_t / __uint128_t are passed differently than char / int / long
+//  (require two registers instead of one) and therefore should be 
discriminated
+//  differently.
+
+// CHECK: @fptr5 = global ptr ptrauth (ptr @external_function_int, i32 0, i64 
2712)
+// CHECK: @fptr6 = global ptr ptrauth (ptr @external_function_char, i32 0, i64 
2712)
+void (*fptr5)(int) = external_function_int;
+void (*fptr6)(char) = external_function_char;
+
+// CHECK: @fptr7 = global ptr ptrauth (ptr @external_function_i128, i32 0, i64 
23141)
+// CHECK: @fptr8 = global ptr ptrauth (ptr @external_function_u128, i32 0, i64 
45743)
+// CHECK: @fptr9 = global ptr ptrauth (ptr @external_function_b128, i32 0, i64 
17854)
+// CHECK: @fptr10 = global ptr ptrauth (ptr @external_function_b8, i32 0, i64 
26383)
+void (*fptr7)(__int128_t) = external_function_i128;
+void (*fptr8)(__uint128_t) = external_function_u128;
+void (*fptr9)(_BitInt(128)) = external_function_b128;
+void (*fptr10)(_BitInt(8)) = external_function_b8;
+
 // CHECK-LABEL: define{{.*}} void @test_call()
 void test_call() {
   // CHECK:      [[T0:%.*]] = load ptr, ptr @fnptr,

>From 9034dfe720e13e94412ae9ac49c4c26da1f15c8f Mon Sep 17 00:00:00 2001
From: Anton Korobeynikov <[email protected]>
Date: Sun, 1 Jun 2025 23:55:32 -0700
Subject: [PATCH 2/2] Make type discrimination of 128-bit types optional

---
 clang/include/clang/Basic/Features.def        |  1 +
 clang/include/clang/Basic/LangOptions.def     |  2 ++
 clang/include/clang/Options/Options.td        |  2 ++
 clang/lib/AST/ASTContext.cpp                  | 21 ++++++++++----
 clang/lib/Driver/ToolChains/Clang.cpp         |  3 ++
 clang/lib/Frontend/CompilerInvocation.cpp     |  4 +++
 .../ptrauth-function-type-discriminator.c     | 28 ++++++++++++-------
 7 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/clang/include/clang/Basic/Features.def 
b/clang/include/clang/Basic/Features.def
index f0a9c4889ea2d..aab2aaa18e5c2 100644
--- a/clang/include/clang/Basic/Features.def
+++ b/clang/include/clang/Basic/Features.def
@@ -164,6 +164,7 @@ FEATURE(ptrauth_indirect_gotos, 
LangOpts.PointerAuthIndirectGotos)
 FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini)
 FEATURE(ptrauth_init_fini_address_discrimination, 
LangOpts.PointerAuthInitFiniAddressDiscrimination)
 FEATURE(ptrauth_elf_got, LangOpts.PointerAuthELFGOT)
+FEATURE(ptrauth_function_pointer_type_discrimination_128, 
LangOpts.PointerAuthFunctionTypeDiscrimination128)
 
 FEATURE(ptrauth_objc_isa, LangOpts.PointerAuthObjcIsa)
 FEATURE(ptrauth_objc_interface_sel, LangOpts.PointerAuthObjcInterfaceSel)
diff --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 1fb491a54a278..8ca0a0de50b56 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -129,6 +129,8 @@ LANGOPT(PointerAuthVTPtrTypeDiscrimination, 1, 0, 
NotCompatible, "incorporate ty
 LANGOPT(PointerAuthTypeInfoVTPtrDiscrimination, 1, 0, NotCompatible, 
"incorporate type and address discrimination in authenticated vtable pointers 
for std::type_info")
 LANGOPT(PointerAuthFunctionTypeDiscrimination, 1, 0, Benign,
         "Use type discrimination when signing function pointers")
+LANGOPT(PointerAuthFunctionTypeDiscrimination128, 1, 0, NotCompatible,
+        "Use different discriminators for __int128_t / __uint128_t / 
_BitInt(n) compared to other integer types when computing function pointer type 
discriminator")
 LANGOPT(PointerAuthInitFini, 1, 0, NotCompatible, "sign function pointers in 
init/fini arrays")
 LANGOPT(PointerAuthInitFiniAddressDiscrimination, 1, 0, NotCompatible,
         "incorporate address discrimination in authenticated function pointers 
in init/fini arrays")
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index b2e32c75e5745..e37ab43b89624 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -4995,6 +4995,8 @@ defm ptrauth_type_info_vtable_pointer_discrimination :
   OptInCC1FFlag<"ptrauth-type-info-vtable-pointer-discrimination", "Enable 
type and address discrimination of vtable pointer of std::type_info">;
 defm ptrauth_function_pointer_type_discrimination : 
OptInCC1FFlag<"ptrauth-function-pointer-type-discrimination",
   "Enable type discrimination on C function pointers">;
+defm ptrauth_128bit_type_discrimination : 
OptInCC1FFlag<"ptrauth-128bit-type-discrimination",
+  "Do not use different discriminators for __int128_t / __uint128_t / 
_BitInt(n) compared to other integer types when computing function pointer type 
discriminator">;
 defm ptrauth_indirect_gotos : OptInCC1FFlag<"ptrauth-indirect-gotos",
   "Enable signing and authentication of indirect goto targets">;
 defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of 
function pointers in init/fini arrays">;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 09d949b5e1643..1766a52197fb8 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3510,11 +3510,14 @@ static void encodeTypeForFunctionPointerAuth(const 
ASTContext &Ctx,
     OS << "?";
     return;
 
-  case Type::BitInt: {
-    const auto *BtTy = T->castAs<BitIntType>();
-    OS << "D" << (BtTy->isUnsigned() ? "U" : "B") << BtTy->getNumBits() << "_";
+  case Type::BitInt:
+    if (Ctx.getLangOpts().PointerAuthFunctionTypeDiscrimination128) {
+      const auto *BtTy = T->castAs<BitIntType>();
+      OS << "D" << (BtTy->isUnsigned() ? "U" : "B") << BtTy->getNumBits()
+         << "_";
+    } else
+      OS << "?";
     return;
-  }
 
   case Type::Builtin: {
     const auto *BTy = T->castAs<BuiltinType>();
@@ -3522,11 +3525,17 @@ static void encodeTypeForFunctionPointerAuth(const 
ASTContext &Ctx,
     switch (Kind) {
 #define SIGNED_TYPE(Id, SingletonId)                                           
\
   case BuiltinType::Id:                                                        
\
-    OS << (Kind == BuiltinType::Int128 ? "n" : "i");                           
\
+    OS << (Kind == BuiltinType::Int128 &&                                      
\
+                   Ctx.getLangOpts().PointerAuthFunctionTypeDiscrimination128  
\
+               ? "n"                                                           
\
+               : "i");                                                         
\
     return;
 #define UNSIGNED_TYPE(Id, SingletonId)                                         
\
   case BuiltinType::Id:                                                        
\
-    OS << (Kind == BuiltinType::UInt128 ? "o" : "i");                          
\
+    OS << (Kind == BuiltinType::UInt128 &&                                     
\
+                   Ctx.getLangOpts().PointerAuthFunctionTypeDiscrimination128  
\
+               ? "o"                                                           
\
+               : "i");                                                         
\
     return;
 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
 #define BUILTIN_TYPE(Id, SingletonId)
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index a30b01a675b99..af073fc952631 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1740,6 +1740,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
         options::OPT_fno_ptrauth_function_pointer_type_discrimination);
     Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_indirect_gotos,
                       options::OPT_fno_ptrauth_indirect_gotos);
+    Args.addOptInFlag(
+        CmdArgs, options::OPT_fptrauth_128bit_type_discrimination,
+        options::OPT_fno_ptrauth_128bit_type_discrimination);
   }
   if (Triple.isOSLinux() &&
       Triple.getEnvironment() == llvm::Triple::PAuthTest) {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 6545307a8c8a7..14e52592f7824 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3603,6 +3603,8 @@ static void GeneratePointerAuthArgs(const LangOptions 
&Opts,
     GenerateArg(Consumer, 
OPT_fptrauth_type_info_vtable_pointer_discrimination);
   if (Opts.PointerAuthFunctionTypeDiscrimination)
     GenerateArg(Consumer, OPT_fptrauth_function_pointer_type_discrimination);
+  if (Opts.PointerAuthFunctionTypeDiscrimination128)
+    GenerateArg(Consumer, OPT_fptrauth_128bit_type_discrimination);
   if (Opts.PointerAuthInitFini)
     GenerateArg(Consumer, OPT_fptrauth_init_fini);
   if (Opts.PointerAuthInitFiniAddressDiscrimination)
@@ -3636,6 +3638,8 @@ static void ParsePointerAuthArgs(LangOptions &Opts, 
ArgList &Args,
       Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination);
   Opts.PointerAuthFunctionTypeDiscrimination =
       Args.hasArg(OPT_fptrauth_function_pointer_type_discrimination);
+  Opts.PointerAuthFunctionTypeDiscrimination128 =
+      Args.hasArg(OPT_fptrauth_128bit_type_discrimination);
   Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
   Opts.PointerAuthInitFiniAddressDiscrimination =
       Args.hasArg(OPT_fptrauth_init_fini_address_discrimination);
diff --git a/clang/test/CodeGen/ptrauth-function-type-discriminator.c 
b/clang/test/CodeGen/ptrauth-function-type-discriminator.c
index 9bf4a8874c3c3..280115862d927 100644
--- a/clang/test/CodeGen/ptrauth-function-type-discriminator.c
+++ b/clang/test/CodeGen/ptrauth-function-type-discriminator.c
@@ -1,18 +1,22 @@
 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \
-// RUN:   -disable-llvm-passes -emit-llvm %s       -o- | FileCheck 
--check-prefixes=CHECK,CHECKC %s
+// RUN:   -disable-llvm-passes -emit-llvm %s       -o- | FileCheck 
--check-prefixes=CHECK,CHECKC,CHECKNO128 %s
 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \
-// RUN:   -disable-llvm-passes -emit-llvm -xc++ %s -o- | FileCheck 
--check-prefix=CHECK %s
+// RUN:   -disable-llvm-passes -emit-llvm -xc++ %s -o- | FileCheck 
--check-prefixes=CHECK,CHECKNO128 %s
 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
arm64-apple-ios    -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast
 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
arm64-apple-ios    -fptrauth-calls -fptrauth-intrinsics \
-// RUN:   -emit-llvm -x ast -o - %t.ast | FileCheck 
--check-prefixes=CHECK,CHECKC %s
+// RUN:   -emit-llvm -x ast -o - %t.ast | FileCheck 
--check-prefixes=CHECK,CHECKC,CHECKNO128 %s
+// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
arm64e-apple-ios13 -fptrauth-calls -fptrauth-intrinsics \
+// RUN:   -fptrauth-128bit-type-discrimination -disable-llvm-passes -emit-llvm 
%s       -o- | FileCheck --check-prefixes=CHECK,CHECKC,CHECK128 %s
 
 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
aarch64-linux-gnu  -fptrauth-calls -fptrauth-intrinsics \
-// RUN:   -disable-llvm-passes -emit-llvm %s       -o- | FileCheck 
--check-prefixes=CHECK,CHECKC %s
+// RUN:   -disable-llvm-passes -emit-llvm %s       -o- | FileCheck 
--check-prefixes=CHECK,CHECKC,CHECKNO128 %s
 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
aarch64-linux-gnu  -fptrauth-calls -fptrauth-intrinsics \
-// RUN:   -disable-llvm-passes -emit-llvm -xc++ %s -o- | FileCheck 
--check-prefix=CHECK %s
+// RUN:   -disable-llvm-passes -emit-llvm -xc++ %s -o- | FileCheck 
--check-prefixes=CHECK,CHECKNO128 %s
 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
aarch64-linux-gnu  -fptrauth-calls -fptrauth-intrinsics -emit-pch %s -o %t.ast
 // RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
aarch64-linux-gnu  -fptrauth-calls -fptrauth-intrinsics \
-// RUN:   -emit-llvm -x ast -o - %t.ast | FileCheck 
--check-prefixes=CHECK,CHECKC %s
+// RUN:   -emit-llvm -x ast -o - %t.ast | FileCheck 
--check-prefixes=CHECK,CHECKC,CHECKNO128 %s
+// RUN: %clang_cc1 -fptrauth-function-pointer-type-discrimination -triple 
aarch64-linux-gnu -fptrauth-calls -fptrauth-intrinsics \
+// RUN:   -fptrauth-128bit-type-discrimination -disable-llvm-passes -emit-llvm 
%s       -o- | FileCheck --check-prefixes=CHECK,CHECKC,CHECK128 %s
 
 #ifdef __cplusplus
 extern "C" {
@@ -87,10 +91,14 @@ extern void external_function_b8(_BitInt(8));
 void (*fptr5)(int) = external_function_int;
 void (*fptr6)(char) = external_function_char;
 
-// CHECK: @fptr7 = global ptr ptrauth (ptr @external_function_i128, i32 0, i64 
23141)
-// CHECK: @fptr8 = global ptr ptrauth (ptr @external_function_u128, i32 0, i64 
45743)
-// CHECK: @fptr9 = global ptr ptrauth (ptr @external_function_b128, i32 0, i64 
17854)
-// CHECK: @fptr10 = global ptr ptrauth (ptr @external_function_b8, i32 0, i64 
26383)
+// CHECK128: @fptr7 = global ptr ptrauth (ptr @external_function_i128, i32 0, 
i64 23141)
+// CHECK128: @fptr8 = global ptr ptrauth (ptr @external_function_u128, i32 0, 
i64 45743)
+// CHECK128: @fptr9 = global ptr ptrauth (ptr @external_function_b128, i32 0, 
i64 17854)
+// CHECK128: @fptr10 = global ptr ptrauth (ptr @external_function_b8, i32 0, 
i64 26383)
+// CHECKNO128: @fptr7 = global ptr ptrauth (ptr @external_function_i128, i32 
0, i64 2712)
+// CHECKNO128: @fptr8 = global ptr ptrauth (ptr @external_function_u128, i32 
0, i64 2712)
+// CHECKNO128: @fptr9 = global ptr ptrauth (ptr @external_function_b128, i32 
0, i64 41228)
+// CHECKNO128: @fptr10 = global ptr ptrauth (ptr @external_function_b8, i32 0, 
i64 41228)
 void (*fptr7)(__int128_t) = external_function_i128;
 void (*fptr8)(__uint128_t) = external_function_u128;
 void (*fptr9)(_BitInt(128)) = external_function_b128;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to