[llvm-branch-commits] [clang] release/19.x: [clang] Wire -fptrauth-returns to "ptrauth-returns" fn attribute. (#102416) (PR #102670)
https://github.com/kovdan01 approved this pull request. https://github.com/llvm/llvm-project/pull/102670 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/19.x: [PAC] Define __builtin_ptrauth_type_discriminator (#100204) (PR #100332)
https://github.com/kovdan01 approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/100332 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] release/19.x: [clang][test] Add function type discrimination tests to static destructor tests (#99604) (PR #100215)
https://github.com/kovdan01 approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/100215 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [compiler-rt] release/19.x: [PAC][compiler-rt][UBSan] Strip signed vptr instead of authenticating it (#100153) (PR #100219)
https://github.com/kovdan01 approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/100219 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 approved this pull request. LGTM, but this needs a rebase - the base branch was updated, and now the PR contains unrelated changes. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s kovdan01 wrote: Thanks. I'm OK with merging this "as is" and enhancing/re-organizing tests as a separate PR. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 approved this pull request. LGTM with a couple of documentation-related comments https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -354,6 +354,23 @@ Given that ``signedPointer`` matches the layout for signed pointers signed with the given key, extract the raw pointer from it. This operation does not trap and cannot fail, even if the pointer is not validly signed. +``ptrauth_sign_constant`` +^ + +.. code-block:: c + + ptrauth_sign_constant(pointer, key, discriminator) + +Return a signed pointer for a constant address in a manner which guarantees +a non-attackable sequence. kovdan01 wrote: Thanks, now I see that. Are you going to submit documentation changes all at once as a separate PR? If it's not too time-consuming, I'd prefer having all related terms defined as a part of this PR (particularly, at least the part "Attackable code sequences"), but I'm OK with submitting documentation changes separately. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -58,6 +58,35 @@ void test_string_discriminator(const char *str) { } +void test_sign_constant(int *dp, int (*fp)(int)) { + __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY); // expected-error {{too few arguments}} + __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, &dv, &dv); // expected-error {{too many arguments}} + + __builtin_ptrauth_sign_constant(mismatched_type, VALID_DATA_KEY, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}} + __builtin_ptrauth_sign_constant(&dv, mismatched_type, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}} + __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, mismatched_type); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}} + + (void) __builtin_ptrauth_sign_constant(NULL, VALID_DATA_KEY, &dv); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}} kovdan01 wrote: Thanks for explanation. I suppose it's OK to leave the way null sign/auth is handled "as is" for this PR and ship changes (if needed) as future patches. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -354,6 +354,23 @@ Given that ``signedPointer`` matches the layout for signed pointers signed with the given key, extract the raw pointer from it. This operation does not trap and cannot fail, even if the pointer is not validly signed. +``ptrauth_sign_constant`` +^ + +.. code-block:: c + + ptrauth_sign_constant(pointer, key, discriminator) + +Return a signed pointer for a constant address in a manner which guarantees +a non-attackable sequence. + +``pointer`` must be a constant expression of pointer type which evaluates to +a non-null pointer. The result will have the same type as ``discriminator``. kovdan01 wrote: Could you please reply to the previous comment in this thread? It was resolved, but the issue with the docs does not seem to be fixed. Please let me know if I miss smth and there is no issue - but, at least, we have different info in rst docs and in ptrauth.h header (the first one says that the result has the same type as `discriminator`, the second one - that the result's type is the same as the type of original value). So, things should at least be consistent. Ideally, we can just use the exact same text for description in both places, but I'm happy with different descriptions if they just match each other. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-calls %s -verify -emit-llvm -o - + +void f(void); + +int *pf = (int *)&f + 1; // expected-error{{cannot compile this static initializer yet}} kovdan01 wrote: > I'll see if I can improve the error message later. Thanks. I'm OK with having the diagnostic "as is" for this PR and submitting a patch with message improvement as another PR later. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -3041,3 +3046,20 @@ llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec, return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name); } + +void CodeGenFunction::EmitPointerAuthOperandBundle( +const CGPointerAuthInfo &PointerAuth, +SmallVectorImpl &Bundles) { + if (!PointerAuth.isSigned()) +return; + + auto Key = Builder.getInt32(PointerAuth.getKey()); kovdan01 wrote: ```suggestion auto *Key = Builder.getInt32(PointerAuth.getKey()); ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 requested changes to this pull request. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -938,6 +939,32 @@ class CodeGenModule : public CodeGenTypeCache { // Return the function body address of the given function. llvm::Constant *GetFunctionStart(const ValueDecl *Decl); + /// Return a function pointer for a reference to the given function. + /// This correctly handles weak references, but does not apply a + /// pointer signature. + llvm::Constant *getRawFunctionPointer(GlobalDecl GD, +llvm::Type *Ty = nullptr); + + /// Return the ABI-correct function pointer value for a reference + /// to the given function. This will apply a pointer signature if + /// necessary, caching the result for the given function. + llvm::Constant *getFunctionPointer(GlobalDecl GD, llvm::Type *Ty = nullptr); + + /// Return the ABI-correct function pointer value for a reference + /// to the given function. This will apply a pointer signature if + /// necessary, but will only cache the result if \p FD is passed. + llvm::Constant *getFunctionPointer(llvm::Constant *Pointer, + QualType FunctionType, + GlobalDecl GD = GlobalDecl()); + + CGPointerAuthInfo getFunctionPointerAuthInfo(QualType T); + + llvm::Constant *getConstantSignedPointer(llvm::Constant *Pointer, kovdan01 wrote: This member function declaration seems to be unused and not corresponding to any definition, so it can probably be removed. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -0,0 +1,13 @@ +// 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 arm64-apple-ios -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,CALLS kovdan01 wrote: I'm OK with any Apple-specific RUN lines if you really want to have all of them, but this one and the next one seem to duplicate each other. I suppose there should be a separate test which checks that arm64e target enabled desired ptrauth flags, and then you can just use either arm64e or arm64 with explicitly specified flags in RUN lines in codegen tests. Feel free to ignore - everything Apple-related is not what I'm going to debate :) https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -triple arm64e-apple-ios -fptrauth-calls %s -verify -emit-llvm -o - + +void f(void); + +int *pf = (int *)&f + 1; // expected-error{{cannot compile this static initializer yet}} kovdan01 wrote: Feel free to ignore: it's probably worth having a more specific error message here. It's not actually obvious why we are erroring out - is this because signing function pointers with non-zero offsets is not supported? Even if we leave this error message as is, it's probably worth at least having a comment here (and in clang/test/CodeGen/ptrauth-function-init.c as wel) https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -61,3 +79,28 @@ CodeGen::getConstantSignedPointer(CodeGenModule &CGM, llvm::Constant *Pointer, return CGM.getConstantSignedPointer(Pointer, Key, StorageAddress, OtherDiscriminator); } + +/// If applicable, sign a given constant function pointer with the ABI rules for +/// functionType. +llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *Pointer, + QualType FunctionType, + GlobalDecl GD) { + assert(FunctionType->isFunctionType() || + FunctionType->isFunctionReferenceType() || + FunctionType->isFunctionPointerType()); + + if (auto PointerAuth = getFunctionPointerAuthInfo(FunctionType)) { +return getConstantSignedPointer( + Pointer, PointerAuth.getKey(), nullptr, kovdan01 wrote: nit ```suggestion Pointer, PointerAuth.getKey(), /*StorageAddress=*/nullptr, ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -3041,3 +3046,20 @@ llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec, return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name); } + +void CodeGenFunction::EmitPointerAuthOperandBundle( +const CGPointerAuthInfo &PointerAuth, +SmallVectorImpl &Bundles) { + if (!PointerAuth.isSigned()) +return; + + auto Key = Builder.getInt32(PointerAuth.getKey()); + + llvm::Value *Discriminator = PointerAuth.getDiscriminator(); + if (!Discriminator) { kovdan01 wrote: nit: omit braces for simple if statements https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -938,6 +939,32 @@ class CodeGenModule : public CodeGenTypeCache { // Return the function body address of the given function. llvm::Constant *GetFunctionStart(const ValueDecl *Decl); + /// Return a function pointer for a reference to the given function. + /// This correctly handles weak references, but does not apply a + /// pointer signature. + llvm::Constant *getRawFunctionPointer(GlobalDecl GD, +llvm::Type *Ty = nullptr); + + /// Return the ABI-correct function pointer value for a reference + /// to the given function. This will apply a pointer signature if + /// necessary, caching the result for the given function. + llvm::Constant *getFunctionPointer(GlobalDecl GD, llvm::Type *Ty = nullptr); + + /// Return the ABI-correct function pointer value for a reference + /// to the given function. This will apply a pointer signature if + /// necessary, but will only cache the result if \p FD is passed. kovdan01 wrote: > but will only cache the result if \p FD is passed. You probably misspelled GD? https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -61,3 +79,28 @@ CodeGen::getConstantSignedPointer(CodeGenModule &CGM, llvm::Constant *Pointer, return CGM.getConstantSignedPointer(Pointer, Key, StorageAddress, OtherDiscriminator); } + +/// If applicable, sign a given constant function pointer with the ABI rules for kovdan01 wrote: Do we need this comments? In CodeGenModule.h, we already have more detailed description. It looks like that other member functions of `CodeGenModule` only contain description in the header, but not in the sources, and there is probably no reason for such duplication when adding new member functions. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -104,10 +109,13 @@ class CGCallee { /// Construct a callee. Call this constructor directly when this /// isn't a direct call. - CGCallee(const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr) + CGCallee( + const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr, + const CGPointerAuthInfo &pointerAuthInfo = /*FIXME*/ CGPointerAuthInfo()) kovdan01 wrote: Thanks for explanation. Do I get it correct that you'll make the parameter mandatory in a subsequent PR since this would require small changes in many places and you don't want to clutter this PR with them? https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -351,6 +351,9 @@ def err_drv_omp_host_ir_file_not_found : Error< "target regions but cannot be found">; def err_drv_omp_host_target_not_supported : Error< "target '%0' is not a supported OpenMP host target">; +def err_drv_ptrauth_not_supported : Error< + "target '%0' does not support native pointer authentication">; kovdan01 wrote: This was marked as resolved, but still looks untested. Do I miss smth? I suppose that on driver side, it's not a problem to have a test case for unsupported target (while I agree that for backend testing the same requires cluttering tests unrelated target). https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -0,0 +1,9 @@ +// RUN: %clang -target arm64-apple-macosx -fptrauth-calls -c %s -### 2>&1 | FileCheck %s --check-prefix PTRAUTH_CALLS kovdan01 wrote: We already have these tests in aarch64-ptrauth.c. If ptrauth.c is a better name for them - consider just renaming the old test file (probably in a separate PR since this one is clang codegen-related) instead of introducing a new one with duplicating checks. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 requested changes to this pull request. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios-emit-llvm %s -o - | FileCheck %s --check-prefixes=ALL,OFF kovdan01 wrote: All the tests introduced in the PR seem not Apple-specific - so, it would be nice if you also add RUN lines for a triple like `aarch64-elf`. Manually specifying `-fptrauth-calls` will be needed since we now don't have an equivalent of Apple's arm64e which enabled desired functionality automatically. This applies to all the tests. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s kovdan01 wrote: Can we move this test file contents to clang/test/CodeGen/ptrauth-function.c? I'm happy with both variants, but now as for me we have many small test files, and combining some of them would not harm readability IMHO since they'll still be small even after concatenating. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -128,12 +136,12 @@ class CGCallee { static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo = CGCalleeInfo()) { -return CGCallee(abstractInfo, functionPtr); +return CGCallee(abstractInfo, functionPtr, CGPointerAuthInfo()); kovdan01 wrote: Even though the parameter is going to be mandatory later (as said in https://github.com/llvm/llvm-project/pull/93906/files#r1636843492), now it's not, so right now there is probably no reason for this change and a similar one below. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -61,3 +79,28 @@ CodeGen::getConstantSignedPointer(CodeGenModule &CGM, llvm::Constant *Pointer, return CGM.getConstantSignedPointer(Pointer, Key, StorageAddress, OtherDiscriminator); } + +/// If applicable, sign a given constant function pointer with the ABI rules for +/// functionType. +llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *Pointer, + QualType FunctionType, + GlobalDecl GD) { kovdan01 wrote: Is `GD` used in the function? https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-calls -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck -check-prefix=CHECK %s + +void test_call(); + +// CHECK-LABEL: define void @test_direct_call() +void test_direct_call() { kovdan01 wrote: Are indirect calls tested? I see clang/test/CodeGen/ptrauth-function-lvalue-cast.c testing indirect call via `char *ptr` casted to desired function type, but I don't see a test when we just have a signed function pointer (for example, passed by an argument to a function) and call the function that way. Please let me know if I miss smth. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [compiler-rt] [PAC][AArch64] Support init/fini array signing (PR #95203)
https://github.com/kovdan01 created https://github.com/llvm/llvm-project/pull/95203 If both `-fptrauth-init-fini` and `-fptrauth-calls` are passed, sign function pointers in `llvm.global_ctors` and `llvm.global_dtors` with constant discriminator 0xD9D4 (`ptrauth_string_discriminator("init_fini")`) and no address discrimination. >From 9880b6883cd73ab2dcd0efd9ae80805db862c595 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Wed, 12 Jun 2024 10:28:08 +0300 Subject: [PATCH] [PAC][AArch64] Support init/fini array signing If both `-fptrauth-init-fini` and `-fptrauth-calls` are passed, sign function pointers in `llvm.global_ctors` and `llvm.global_dtors` with constant discriminator 0xD9D4 (`ptrauth_string_discriminator("init_fini")`) and no address discrimination. --- .../include/clang/Basic/PointerAuthOptions.h | 7 +++ clang/lib/CodeGen/CodeGenModule.cpp | 50 +++ clang/lib/Frontend/CompilerInvocation.cpp | 5 ++ clang/lib/Headers/ptrauth.h | 7 +++ clang/test/CodeGen/ptrauth-init-fini.c| 27 ++ compiler-rt/lib/builtins/crtbegin.c | 16 ++ 6 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 clang/test/CodeGen/ptrauth-init-fini.c diff --git a/clang/include/clang/Basic/PointerAuthOptions.h b/clang/include/clang/Basic/PointerAuthOptions.h index 32b179e3f9460..dea8ae439a0eb 100644 --- a/clang/include/clang/Basic/PointerAuthOptions.h +++ b/clang/include/clang/Basic/PointerAuthOptions.h @@ -25,6 +25,10 @@ namespace clang { +/// Constant discriminator to be used with function pointers in .init_array and +/// .fini_array. The value is ptrauth_string_discriminator("init_fini") +constexpr uint16_t InitFiniPointerConstantDiscriminator = 0xD9D4; + constexpr unsigned PointerAuthKeyNone = -1; class PointerAuthSchema { @@ -152,6 +156,9 @@ class PointerAuthSchema { struct PointerAuthOptions { /// The ABI for C function pointers. PointerAuthSchema FunctionPointers; + + /// The ABI for function addresses in .init_array and .fini_array + PointerAuthSchema InitFiniPointers; }; } // end namespace clang diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e4774a587707a..6bc6c34a9f524 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2042,37 +2042,47 @@ void CodeGenModule::AddGlobalDtor(llvm::Function *Dtor, int Priority, void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) { if (Fns.empty()) return; - // Ctor function type is void()*. - llvm::FunctionType* CtorFTy = llvm::FunctionType::get(VoidTy, false); - llvm::Type *CtorPFTy = llvm::PointerType::get(CtorFTy, - TheModule.getDataLayout().getProgramAddressSpace()); + const PointerAuthSchema &InitFiniAuthSchema = + getCodeGenOpts().PointerAuth.InitFiniPointers; + assert(!InitFiniAuthSchema || !InitFiniAuthSchema.isAddressDiscriminated()); - // Get the type of a ctor entry, { i32, void ()*, i8* }. - llvm::StructType *CtorStructTy = llvm::StructType::get( - Int32Ty, CtorPFTy, VoidPtrTy); + // Ctor function type is ptr. + llvm::PointerType *PtrTy = llvm::PointerType::get( + getLLVMContext(), TheModule.getDataLayout().getProgramAddressSpace()); + + // Get the type of a ctor entry, { i32, ptr, ptr }. + llvm::StructType *CtorStructTy = llvm::StructType::get(Int32Ty, PtrTy, PtrTy); // Construct the constructor and destructor arrays. - ConstantInitBuilder builder(*this); - auto ctors = builder.beginArray(CtorStructTy); + ConstantInitBuilder Builder(*this); + auto Ctors = Builder.beginArray(CtorStructTy); for (const auto &I : Fns) { -auto ctor = ctors.beginStruct(CtorStructTy); -ctor.addInt(Int32Ty, I.Priority); -ctor.add(I.Initializer); +auto Ctor = Ctors.beginStruct(CtorStructTy); +Ctor.addInt(Int32Ty, I.Priority); +if (InitFiniAuthSchema) { + llvm::Constant *SignedCtorPtr = getConstantSignedPointer( + I.Initializer, InitFiniAuthSchema.getKey(), + /*StorageAddress=*/nullptr, + llvm::ConstantInt::get( + SizeTy, InitFiniAuthSchema.getConstantDiscrimination())); + Ctor.add(SignedCtorPtr); +} else { + Ctor.add(I.Initializer); +} if (I.AssociatedData) - ctor.add(I.AssociatedData); + Ctor.add(I.AssociatedData); else - ctor.addNullPointer(VoidPtrTy); -ctor.finishAndAddTo(ctors); + Ctor.addNullPointer(PtrTy); +Ctor.finishAndAddTo(Ctors); } - auto list = -ctors.finishAndCreateGlobal(GlobalName, getPointerAlign(), -/*constant*/ false, -llvm::GlobalValue::AppendingLinkage); + auto List = Ctors.finishAndCreateGlobal(GlobalName, getPointerAlign(), + /*constant*/ false, + llvm::GlobalValue::AppendingLinkage); // The LTO linker doesn
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -354,6 +354,23 @@ Given that ``signedPointer`` matches the layout for signed pointers signed with the given key, extract the raw pointer from it. This operation does not trap and cannot fail, even if the pointer is not validly signed. +``ptrauth_sign_constant`` +^ + +.. code-block:: c + + ptrauth_sign_constant(pointer, key, discriminator) + +Return a signed pointer for a constant address in a manner which guarantees +a non-attackable sequence. kovdan01 wrote: It would be nice to have this term described more deeply. Do you mean an absence of a signing oracle when talking about a non-attackable sequence? https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2074,16 +2091,91 @@ static bool checkPointerAuthValue(Sema &S, Expr *&Arg, if (convertArgumentToType(S, Arg, ExpectedTy)) return true; - // Warn about null pointers for non-generic sign and auth operations. - if ((OpKind == PAO_Sign || OpKind == PAO_Auth) && - Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) { -S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign - ? diag::warn_ptrauth_sign_null_pointer - : diag::warn_ptrauth_auth_null_pointer) -<< Arg->getSourceRange(); + if (!RequireConstant) { +// Warn about null pointers for non-generic sign and auth operations. +if ((OpKind == PAO_Sign || OpKind == PAO_Auth) && +Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) { + S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign +? diag::warn_ptrauth_sign_null_pointer +: diag::warn_ptrauth_auth_null_pointer) + << Arg->getSourceRange(); +} + +return false; } - return false; + // Perform special checking on the arguments to ptrauth_sign_constant. + + // The main argument. + if (OpKind == PAO_Sign) { +// Require the value we're signing to have a special form. +auto BaseOffsetPair = findConstantBaseAndOffset(S, Arg); +bool Invalid; + +// Must be rooted in a declaration reference. +if (!BaseOffsetPair.first) { + Invalid = true; kovdan01 wrote: It's probably out of scope of this patch and may be just considered (or maybe not :) ) as a TODO for future enhancements - it's probably worth having separate error messages for different `Invalid = true` cases. This applies to both `err_ptrauth_bad_constant_discriminator` and `err_ptrauth_bad_constant_pointer`. Feel free to ignore though. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-elf -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s + +extern int external; + +// CHECK: @ptr1 = global ptr ptrauth (ptr @external, i32 0, i64 26) +void *ptr1 = __builtin_ptrauth_sign_constant(&external, 0, 26); + +// CHECK: @ptr2 = global ptr ptrauth (ptr @external, i32 2, i64 26, ptr @ptr2) +void *ptr2 = __builtin_ptrauth_sign_constant(&external, 2, __builtin_ptrauth_blend_discriminator(&ptr2, 26)); + +// CHECK: @ptr3 = global ptr null +void *ptr3; + +void test_sign_constant_code() { kovdan01 wrote: It's probably worth to have the exact same tests for global and function-local variables to ensure that everything is OK in both contexts. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2074,16 +2091,91 @@ static bool checkPointerAuthValue(Sema &S, Expr *&Arg, if (convertArgumentToType(S, Arg, ExpectedTy)) return true; - // Warn about null pointers for non-generic sign and auth operations. - if ((OpKind == PAO_Sign || OpKind == PAO_Auth) && - Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) { -S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign - ? diag::warn_ptrauth_sign_null_pointer - : diag::warn_ptrauth_auth_null_pointer) -<< Arg->getSourceRange(); + if (!RequireConstant) { +// Warn about null pointers for non-generic sign and auth operations. +if ((OpKind == PAO_Sign || OpKind == PAO_Auth) && +Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) { + S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign +? diag::warn_ptrauth_sign_null_pointer +: diag::warn_ptrauth_auth_null_pointer) + << Arg->getSourceRange(); +} + +return false; } - return false; + // Perform special checking on the arguments to ptrauth_sign_constant. + + // The main argument. + if (OpKind == PAO_Sign) { +// Require the value we're signing to have a special form. +auto BaseOffsetPair = findConstantBaseAndOffset(S, Arg); +bool Invalid; + +// Must be rooted in a declaration reference. +if (!BaseOffsetPair.first) { + Invalid = true; + + // If it's a function declaration, we can't have an offset. +} else if (isa(BaseOffsetPair.first)) { + Invalid = !BaseOffsetPair.second.isZero(); + + // Otherwise we're fine. +} else { + Invalid = false; +} + +if (Invalid) { kovdan01 wrote: Consider omitting braces: https://www.llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2074,16 +2091,91 @@ static bool checkPointerAuthValue(Sema &S, Expr *&Arg, if (convertArgumentToType(S, Arg, ExpectedTy)) return true; - // Warn about null pointers for non-generic sign and auth operations. - if ((OpKind == PAO_Sign || OpKind == PAO_Auth) && - Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) { -S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign - ? diag::warn_ptrauth_sign_null_pointer - : diag::warn_ptrauth_auth_null_pointer) -<< Arg->getSourceRange(); + if (!RequireConstant) { +// Warn about null pointers for non-generic sign and auth operations. +if ((OpKind == PAO_Sign || OpKind == PAO_Auth) && +Arg->isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNull)) { + S.Diag(Arg->getExprLoc(), OpKind == PAO_Sign +? diag::warn_ptrauth_sign_null_pointer +: diag::warn_ptrauth_auth_null_pointer) + << Arg->getSourceRange(); +} + +return false; } - return false; + // Perform special checking on the arguments to ptrauth_sign_constant. + + // The main argument. + if (OpKind == PAO_Sign) { +// Require the value we're signing to have a special form. +auto BaseOffsetPair = findConstantBaseAndOffset(S, Arg); kovdan01 wrote: Wouldn't this become easier to read if you use structured bindings declaration like this: ```suggestion auto [BaseDecl, Offset] = findConstantBaseAndOffset(S, Arg); ``` And below use `BaseDecl` instead of `BaseOffsetPair.first` and `Offset` instead of `BaseOffsetPair.second`? You do not use the pair itself, only its individual members, so just initializing them and having their names short and descriptive looks preferable to me. Also applies to other usage of `findConstantBaseAndOffset` below. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2061,6 +2071,58 @@ ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) { } } +ConstantLValue +ConstantLValueEmitter::emitPointerAuthSignConstant(const CallExpr *E) { + llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->getArg(0)); + unsigned Key = emitPointerAuthKey(E->getArg(1)); + llvm::Constant *StorageAddress; + llvm::Constant *OtherDiscriminator; + std::tie(StorageAddress, OtherDiscriminator) = kovdan01 wrote: Maybe just use a structured binding declaration like this? ``` auto [StorageAddress, OtherDiscriminator] = emitPointerAuthDiscriminator(E->getArg(2)); ``` Or do you want to have separate declarations with explicitly set types? https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 requested changes to this pull request. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2061,6 +2071,58 @@ ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) { } } +ConstantLValue +ConstantLValueEmitter::emitPointerAuthSignConstant(const CallExpr *E) { + llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->getArg(0)); + unsigned Key = emitPointerAuthKey(E->getArg(1)); + llvm::Constant *StorageAddress; + llvm::Constant *OtherDiscriminator; + std::tie(StorageAddress, OtherDiscriminator) = + emitPointerAuthDiscriminator(E->getArg(2)); + + llvm::Constant *SignedPointer = CGM.getConstantSignedPointer( + UnsignedPointer, Key, StorageAddress, OtherDiscriminator); + return SignedPointer; +} + +llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(const Expr *E) { + Expr::EvalResult Result; + bool Succeeded = E->EvaluateAsRValue(Result, CGM.getContext()); + assert(Succeeded); + (void)Succeeded; + + // The assertions here are all checked by Sema. + assert(Result.Val.isLValue()); + return ConstantEmitter(CGM, Emitter.CGF) + .emitAbstract(E->getExprLoc(), Result.Val, E->getType()); +} + +unsigned ConstantLValueEmitter::emitPointerAuthKey(const Expr *E) { + return E->EvaluateKnownConstInt(CGM.getContext()).getZExtValue(); +} + +std::pair +ConstantLValueEmitter::emitPointerAuthDiscriminator(const Expr *E) { + E = E->IgnoreParens(); + + if (auto *Call = dyn_cast(E)) { +if (Call->getBuiltinCallee() == +Builtin::BI__builtin_ptrauth_blend_discriminator) { + llvm::Constant *Pointer = ConstantEmitter(CGM).emitAbstract( + Call->getArg(0), Call->getArg(0)->getType()); + llvm::Constant *Extra = ConstantEmitter(CGM).emitAbstract( + Call->getArg(1), Call->getArg(1)->getType()); + return {Pointer, Extra}; +} + } + + llvm::Constant *Result = ConstantEmitter(CGM).emitAbstract(E, E->getType()); + if (Result->getType()->isPointerTy()) +return {Result, nullptr}; + else kovdan01 wrote: Do not use else after return https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -938,6 +938,11 @@ class CodeGenModule : public CodeGenTypeCache { // Return the function body address of the given function. llvm::Constant *GetFunctionStart(const ValueDecl *Decl); + llvm::Constant *getConstantSignedPointer(llvm::Constant *Pointer, + unsigned Key, + llvm::Constant *StorageAddress, + llvm::Constant *ExtraDiscrim); kovdan01 wrote: Here, this is called `ExtraDiscrim`, in clang/lib/CodeGen/CGPointerAuth.cpp - `OtherDiscriminator`. I suppose that for exact same function its argument names should be the same in the declaration and the definition. I actually suggest to unify this naming all over the pauth-related changes - having one term for a thing is better than mixing several ones for ease of understanding and also helps grepping. Or do I miss smth and extra discriminator is somehow different from other discriminator? https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -354,6 +354,23 @@ Given that ``signedPointer`` matches the layout for signed pointers signed with the given key, extract the raw pointer from it. This operation does not trap and cannot fail, even if the pointer is not validly signed. +``ptrauth_sign_constant`` +^ + +.. code-block:: c + + ptrauth_sign_constant(pointer, key, discriminator) + +Return a signed pointer for a constant address in a manner which guarantees +a non-attackable sequence. + +``pointer`` must be a constant expression of pointer type which evaluates to +a non-null pointer. The result will have the same type as ``discriminator``. kovdan01 wrote: `key` type is not described here (should be `ptrauth_key` as in comments in ptrauth.h) https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2030,8 +2030,25 @@ bool Sema::checkConstantPointerAuthKey(Expr *Arg, unsigned &Result) { return false; } +static std::pair +findConstantBaseAndOffset(Sema &S, Expr *E) { + // Must evaluate as a pointer. + Expr::EvalResult Result; + if (!E->EvaluateAsRValue(Result, S.Context) || !Result.Val.isLValue()) +return std::make_pair(nullptr, CharUnits()); kovdan01 wrote: Feel free to ignore: use of `std::make_pair` is not required in this context, so you can just write the following: ```suggestion return {nullptr, CharUnits()}; ``` Also applies to a couple of usages of `std::make_pair` below. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-elf -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s + +extern int external; + +// CHECK: @ptr1 = global ptr ptrauth (ptr @external, i32 0, i64 26) +void *ptr1 = __builtin_ptrauth_sign_constant(&external, 0, 26); + +// CHECK: @ptr2 = global ptr ptrauth (ptr @external, i32 2, i64 26, ptr @ptr2) +void *ptr2 = __builtin_ptrauth_sign_constant(&external, 2, __builtin_ptrauth_blend_discriminator(&ptr2, 26)); + +// CHECK: @ptr3 = global ptr null +void *ptr3; kovdan01 wrote: Feel free to ignore: probably worth adding test for smth like ``` void *ptr4 = __builtin_ptrauth_sign_constant(&external, 0, NULL); ``` This doesn't bring that much value over testing a non-null constant integer discriminator, but: 1. In docs, having null pointer as a discriminator is listed as a separate option > This is a constant expression if the extra data is an integer or null pointer constant. 2. With `NULL` defined as `#define NULL ((void*) 0)`, we'll explicitly test having a constant pointer, not an integer, value as a discriminator https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -354,6 +354,23 @@ Given that ``signedPointer`` matches the layout for signed pointers signed with the given key, extract the raw pointer from it. This operation does not trap and cannot fail, even if the pointer is not validly signed. +``ptrauth_sign_constant`` +^ + +.. code-block:: c + + ptrauth_sign_constant(pointer, key, discriminator) + +Return a signed pointer for a constant address in a manner which guarantees +a non-attackable sequence. + +``pointer`` must be a constant expression of pointer type which evaluates to +a non-null pointer. The result will have the same type as ``discriminator``. kovdan01 wrote: > The result will have the same type as ``discriminator`` Will it? I suppose this should have the same type as `pointer`, shouldn't it? See also ptrauth.h: > The result will have the same type as the original value. And see also a comment https://github.com/llvm/llvm-project/pull/93903#discussion_r1633197979 https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2030,8 +2030,25 @@ bool Sema::checkConstantPointerAuthKey(Expr *Arg, unsigned &Result) { return false; } +static std::pair +findConstantBaseAndOffset(Sema &S, Expr *E) { + // Must evaluate as a pointer. + Expr::EvalResult Result; + if (!E->EvaluateAsRValue(Result, S.Context) || !Result.Val.isLValue()) +return std::make_pair(nullptr, CharUnits()); + + // Base must be a declaration and can't be weakly imported. kovdan01 wrote: Is there a test for this case? https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
@@ -328,6 +328,21 @@ be done in a single instruction with an immediate integer. ``pointer`` must have pointer type, and ``integer`` must have integer type. The result has type ``ptrauth_extra_data_t``. +``ptrauth_string_discriminator`` + + +.. code-block:: c + + ptrauth_string_discriminator(string) + +Produce a discriminator value for the given string. ``string`` must be +a string literal of ``char`` character type. The result has type +``ptrauth_extra_data_t``. + +The result is always a constant expression. The result value is never zero and +always within range for both the ``__ptrauth`` qualifier and kovdan01 wrote: Since we are talking about ranges here, it would be nice to have these ranges explicitly described in corresponding parts of docs. As far as I understand, different implementations are allowed to have different constraints on discriminator. It would be nice to somewhere describe actual figures for some specific implementation, e.g. arm64e. Please let me know if there is already a place for that which I've missed. https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
@@ -112,6 +135,17 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t; #define ptrauth_auth_data(__value, __old_key, __old_data) \ __builtin_ptrauth_auth(__value, __old_key, __old_data) +/* Compute a constant discriminator from the given string. + + The result can be used as the second argument to + ptrauth_blend_discriminator or the third argument to the + __ptrauth qualifier. It has type size_t. kovdan01 wrote: > It has type size_t. Is it actually size_t? I suppose this should be `ptrauth_extra_data_t` (and in clang/docs/PointerAuthentication.rst, we have `ptrauth_extra_data_t`). One more thought (also applies to #93904, #93906 and any other PRs touching both the rst docs and ptrauth.h header) - can we just use the exact same text for the rst docs and for the comments in the header? https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [llvm] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
https://github.com/kovdan01 commented: @ahmedbougacha After the latest force-push, the PR seems to contain SipHash-related changes from PRs 93902, 94393 and 94394. Could you please limit the changes only to those which are actually being intended to be merged as a part of this PR and resolve merge conflicts with the base branch? I'd like to take one more look at this since there were updates since my latest feedback, but with different changes mixed, it's a bit messy. https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include + namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +class PointerAuthSchema { +public: + enum class Kind : unsigned { +None, +ARM8_3, + }; + + /// Hardware pointer-signing keys in ARM8.3. + /// + /// These values are the same used in ptrauth.h. + enum class ARM8_3Key : unsigned { +ASIA = 0, +ASIB = 1, +ASDA = 2, +ASDB = 3 + }; + + /// Forms of extra discrimination. + enum class Discrimination : unsigned { +/// No additional discrimination. +None, + +/// Discriminate using a constant value. +Constant, + }; + +private: + Kind TheKind : 2; + unsigned IsAddressDiscriminated : 1; kovdan01 wrote: > I guess we should use `unsigned` as the underlying type of bitfields in > `class CGPointerAuthInfo` too. This works for me, thanks https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2061,6 +2071,58 @@ ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) { } } +ConstantLValue +ConstantLValueEmitter::emitPointerAuthSignConstant(const CallExpr *E) { + llvm::Constant *UnsignedPointer = emitPointerAuthPointer(E->getArg(0)); + unsigned Key = emitPointerAuthKey(E->getArg(1)); + llvm::Constant *StorageAddress; + llvm::Constant *OtherDiscriminator; + std::tie(StorageAddress, OtherDiscriminator) = + emitPointerAuthDiscriminator(E->getArg(2)); + + llvm::Constant *SignedPointer = CGM.getConstantSignedPointer( + UnsignedPointer, Key, StorageAddress, OtherDiscriminator); + return SignedPointer; +} + +llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(const Expr *E) { + Expr::EvalResult Result; + bool Succeeded = E->EvaluateAsRValue(Result, CGM.getContext()); + assert(Succeeded); + (void)Succeeded; + + // The assertions here are all checked by Sema. + assert(Result.Val.isLValue()); + return ConstantEmitter(CGM, Emitter.CGF) + .emitAbstract(E->getExprLoc(), Result.Val, E->getType()); +} + +unsigned ConstantLValueEmitter::emitPointerAuthKey(const Expr *E) { + return E->EvaluateKnownConstInt(CGM.getContext()).getZExtValue(); +} + +std::pair +ConstantLValueEmitter::emitPointerAuthDiscriminator(const Expr *E) { + E = E->IgnoreParens(); + + if (auto *Call = dyn_cast(E)) { kovdan01 wrote: ```suggestion if (const auto *Call = dyn_cast(E)) { ``` https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -1856,6 +1856,12 @@ class ConstantLValueEmitter : public ConstStmtVisitor kovdan01 wrote: >From the function prototype, it's unclear that the first element of the pair >stands for `StorageAddress` and the second one - for `OtherDiscriminator`. >Consider adding a comment or, alternatively, using a named structure instead >of `std::pair` (would break `std::tie` usage though) https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -0,0 +1,63 @@ +//===--- CGPointerAuth.cpp - IR generation for pointer authentication -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file contains common routines relating to the emission of +// pointer authentication operations. +// +//===--===// + +#include "CodeGenModule.h" +#include "clang/CodeGen/CodeGenABITypes.h" + +using namespace clang; +using namespace CodeGen; + +/// Build a signed-pointer "ptrauth" constant. +static llvm::ConstantPtrAuth * +buildConstantAddress(CodeGenModule &CGM, llvm::Constant *Pointer, unsigned Key, + llvm::Constant *StorageAddress, + llvm::Constant *OtherDiscriminator) { + llvm::Constant *AddressDiscriminator = nullptr; kovdan01 wrote: Do we need to set this to `nullptr`? We 100% define this in either `if` or `else` branch and do not use the unitialized value before. Same applies to `IntegerDiscriminator` below. You can also use smth like ``` llvm::Constant *AddressDiscriminator = (StorageAddress ? StorageAddress : llvm::Constant::getNullValue(CGM.UnqualPtrTy)); assert(!StorageAddress || (StorageAddress->getType() == CGM.UnqualPtrTy)); ``` https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 requested changes to this pull request. https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -351,6 +351,9 @@ def err_drv_omp_host_ir_file_not_found : Error< "target regions but cannot be found">; def err_drv_omp_host_target_not_supported : Error< "target '%0' is not a supported OpenMP host target">; +def err_drv_ptrauth_not_supported : Error< + "target '%0' does not support native pointer authentication">; kovdan01 wrote: This error message looks untested https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -75,3 +93,36 @@ CodeGen::getConstantSignedPointer(CodeGenModule &CGM, return CGM.getConstantSignedPointer(pointer, key, storageAddress, otherDiscriminator); } + +/// If applicable, sign a given constant function pointer with the ABI rules for +/// functionType. +llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *pointer, + QualType functionType, + GlobalDecl GD) { + assert(functionType->isFunctionType() || + functionType->isFunctionReferenceType() || + functionType->isFunctionPointerType()); + + if (auto pointerAuth = getFunctionPointerAuthInfo(functionType)) { +return getConstantSignedPointer( + pointer, pointerAuth.getKey(), nullptr, + cast_or_null(pointerAuth.getDiscriminator())); + } + + return pointer; +} + +llvm::Constant *CodeGenModule::getFunctionPointer(GlobalDecl GD, + llvm::Type *Ty) { + const FunctionDecl *FD = cast(GD.getDecl()); kovdan01 wrote: nit ```suggestion const auto *FD = cast(GD.getDecl()); ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include + namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +class PointerAuthSchema { +public: + enum class Kind : unsigned { +None, +ARM8_3, + }; + + /// Hardware pointer-signing keys in ARM8.3. + /// + /// These values are the same used in ptrauth.h. + enum class ARM8_3Key : unsigned { +ASIA = 0, +ASIB = 1, +ASDA = 2, +ASDB = 3 + }; + + /// Forms of extra discrimination. + enum class Discrimination : unsigned { +/// No additional discrimination. +None, + +/// Discriminate using a constant value. +Constant, + }; + +private: + Kind TheKind : 2; + unsigned IsAddressDiscriminated : 1; + unsigned IsIsaPointer : 1; + unsigned AuthenticatesNullValues : 1; + PointerAuthenticationMode SelectedAuthenticationMode : 2; + Discrimination DiscriminationKind : 2; + unsigned Key : 4; + unsigned ConstantDiscriminator : 16; + +public: + PointerAuthSchema() : TheKind(Kind::None) {} + + PointerAuthSchema( + ARM8_3Key Key, bool IsAddressDiscriminated, + PointerAuthenticationMode AuthenticationMode, + Discrimination OtherDiscrimination, + std::optional ConstantDiscriminatorOrNone = std::nullopt, + bool IsIsaPointer = false, bool AuthenticatesNullValues = false) + : TheKind(Kind::ARM8_3), IsAddressDiscriminated(IsAddressDiscriminated), +IsIsaPointer(IsIsaPointer), +AuthenticatesNullValues(AuthenticatesNullValues), +SelectedAuthenticationMode(AuthenticationMode), +DiscriminationKind(OtherDiscrimination), Key(unsigned(Key)) { kovdan01 wrote: Consider using `llvm::to_underlying` from llvm/ADT/STLForwardCompat.h: ```suggestion DiscriminationKind(OtherDiscrimination), Key(llvm::to_underlying(Key)) { ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -28,6 +28,24 @@ using namespace clang; using namespace CodeGen; +/// Return the abstract pointer authentication schema for a pointer to the given +/// function type. +CGPointerAuthInfo CodeGenModule::getFunctionPointerAuthInfo(QualType T) { + auto &Schema = getCodeGenOpts().PointerAuth.FunctionPointers; kovdan01 wrote: ```suggestion const auto &Schema = getCodeGenOpts().PointerAuth.FunctionPointers; ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 requested changes to this pull request. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include + namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +class PointerAuthSchema { +public: + enum class Kind : unsigned { +None, +ARM8_3, + }; + + /// Hardware pointer-signing keys in ARM8.3. + /// + /// These values are the same used in ptrauth.h. + enum class ARM8_3Key : unsigned { +ASIA = 0, +ASIB = 1, +ASDA = 2, +ASDB = 3 + }; + + /// Forms of extra discrimination. + enum class Discrimination : unsigned { +/// No additional discrimination. +None, + +/// Discriminate using a constant value. +Constant, + }; + +private: + Kind TheKind : 2; + unsigned IsAddressDiscriminated : 1; + unsigned IsIsaPointer : 1; + unsigned AuthenticatesNullValues : 1; + PointerAuthenticationMode SelectedAuthenticationMode : 2; + Discrimination DiscriminationKind : 2; + unsigned Key : 4; + unsigned ConstantDiscriminator : 16; + +public: + PointerAuthSchema() : TheKind(Kind::None) {} + + PointerAuthSchema( + ARM8_3Key Key, bool IsAddressDiscriminated, + PointerAuthenticationMode AuthenticationMode, + Discrimination OtherDiscrimination, + std::optional ConstantDiscriminatorOrNone = std::nullopt, + bool IsIsaPointer = false, bool AuthenticatesNullValues = false) + : TheKind(Kind::ARM8_3), IsAddressDiscriminated(IsAddressDiscriminated), +IsIsaPointer(IsIsaPointer), +AuthenticatesNullValues(AuthenticatesNullValues), +SelectedAuthenticationMode(AuthenticationMode), +DiscriminationKind(OtherDiscrimination), Key(unsigned(Key)) { +assert((getOtherDiscrimination() != Discrimination::Constant || +ConstantDiscriminatorOrNone) && + "constant discrimination requires a constant!"); +if (ConstantDiscriminatorOrNone) + ConstantDiscriminator = *ConstantDiscriminatorOrNone; + } + + PointerAuthSchema( + ARM8_3Key Key, bool IsAddressDiscriminated, + Discrimination OtherDiscrimination, + std::optional ConstantDiscriminatorOrNone = std::nullopt, + bool IsIsaPointer = false, bool AuthenticatesNullValues = false) + : PointerAuthSchema(Key, IsAddressDiscriminated, + PointerAuthenticationMode::SignAndAuth, + OtherDiscrimination, ConstantDiscriminatorOrNone, + IsIsaPointer, AuthenticatesNullValues) {} + + Kind getKind() const { return TheKind; } + + explicit operator bool() const { return isEnabled(); } + + bool isEnabled() const { return getKind() != Kind::None; } + + bool isAddressDiscriminated() const { +assert(getKind() != Kind::None); +return IsAddressDiscriminated; + } + + bool isIsaPointer() const { +assert(getKind() != Kind::None); +return IsIsaPointer; + } + + bool authenticatesNullValues() const { +assert(getKind() != Kind::None); +return AuthenticatesNullValues; + } + + bool hasOtherDiscrimination() const { +return getOtherDiscrimination() != Discrimination::None; + } + + Discrimination getOtherDiscrimination() const { +assert(getKind() != Kind::None); +return DiscriminationKind; + } + + uint16_t getConstantDiscrimination() const { +assert(getOtherDiscrimination() == Discrimination::Constant); +return (uint16_t)ConstantDiscriminator; kovdan01 wrote: Is the manual cast really needed? The following works for me just fine: ```suggestion return ConstantDiscriminator; ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -75,3 +93,36 @@ CodeGen::getConstantSignedPointer(CodeGenModule &CGM, return CGM.getConstantSignedPointer(pointer, key, storageAddress, otherDiscriminator); } + +/// If applicable, sign a given constant function pointer with the ABI rules for +/// functionType. +llvm::Constant *CodeGenModule::getFunctionPointer(llvm::Constant *pointer, kovdan01 wrote: `PascalCase` for variables in this function and all over the file - it's a new file, so IMHO there is no reason to stick with old naming conventions https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -26,6 +26,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/NoSanitizeList.h" +#include "clang/Basic/PointerAuthOptions.h" kovdan01 wrote: This include looks unneeded since further forward declaration `class PointerAuthSchema;` does the job https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -3041,3 +3046,20 @@ llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec, return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name); } + +void CodeGenFunction::EmitPointerAuthOperandBundle( +const CGPointerAuthInfo &pointerAuth, +SmallVectorImpl &bundles) { + if (!pointerAuth.isSigned()) +return; + + auto key = Builder.getInt32(pointerAuth.getKey()); kovdan01 wrote: ```suggestion auto *Key = Builder.getInt32(pointerAuth.getKey()); ``` https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -104,10 +109,13 @@ class CGCallee { /// Construct a callee. Call this constructor directly when this /// isn't a direct call. - CGCallee(const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr) + CGCallee( + const CGCalleeInfo &abstractInfo, llvm::Value *functionPtr, + const CGPointerAuthInfo &pointerAuthInfo = /*FIXME*/ CGPointerAuthInfo()) kovdan01 wrote: Could you please provide additional context for this FIXME? https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -3041,3 +3046,20 @@ llvm::Value *CodeGenFunction::emitBoolVecConversion(llvm::Value *SrcVec, return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name); } + +void CodeGenFunction::EmitPointerAuthOperandBundle( kovdan01 wrote: `PascalCase` for variables in this function - surrounding code already uses this naming convention https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include + namespace clang { constexpr unsigned PointerAuthKeyNone = -1; +class PointerAuthSchema { +public: + enum class Kind : unsigned { +None, +ARM8_3, + }; + + /// Hardware pointer-signing keys in ARM8.3. + /// + /// These values are the same used in ptrauth.h. + enum class ARM8_3Key : unsigned { +ASIA = 0, +ASIB = 1, +ASDA = 2, +ASDB = 3 + }; + + /// Forms of extra discrimination. + enum class Discrimination : unsigned { +/// No additional discrimination. +None, + +/// Discriminate using a constant value. +Constant, + }; + +private: + Kind TheKind : 2; + unsigned IsAddressDiscriminated : 1; kovdan01 wrote: Do I get it correct that you use `unsigned` for all bit fields instead of `bool IsXXX : 1` for flags and just `uint16_t ConstantDiscriminator` because you rely on some implementation-defined behavior which makes packing fields of the same types more efficient? If you do not rely on that, having more specific types looks more appropriate. In `class CGPointerAuthInfo` you use different types for bit fields (e.g. `bool IsXXX : 1` is used for flags). So, it's better to keep things consistent and also use such convention here (or, alternatively, use `unsigned` everywhere if there is a strong reason for this) https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Implement function pointer signing and authenticated function calls (PR #93906)
@@ -14,10 +14,146 @@ #ifndef LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H #define LLVM_CLANG_BASIC_POINTERAUTHOPTIONS_H +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Target/TargetOptions.h" +#include +#include +#include +#include kovdan01 wrote: There are several unneeded includes (vector, map, ...). If I'm not mistaken, only clang/Basic/LangOptions.h and llvm/Support/ErrorHandling.h are required. https://github.com/llvm/llvm-project/pull/93906 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Support] Add SipHash-based 16-bit ptrauth stable hash. (PR #93902)
kovdan01 wrote: > * we're now left with only the thin wrapper (the 16-bit one only here) and > the simple unittests The wrapper and the tests LGTM https://github.com/llvm/llvm-project/pull/93902 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [Support] Integrate SipHash.cpp into libSupport. (PR #94394)
kovdan01 wrote: @ahmedbougacha The "original" PR #93902 (which was "split" into this one and PR94393) contained some tests, while I don't see any tests now. Will they be added in a follow-up patch or you plan to add them as a part of this one? https://github.com/llvm/llvm-project/pull/94394 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
https://github.com/kovdan01 dismissed https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
https://github.com/kovdan01 commented: LGTM, but I want someone else with deeper understanding of the context to take a look before this gets merged. https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
kovdan01 wrote: It would be nice to also add a run line against `aarch64` or `aarch64-elf` generic triple in this and other tests (see code below). The logic tested is not apple-specific. The test would need a slight change since IR for ELF has functions marked as `dso_local` - you might probably want to use smth like `// CHECK-LABEL: define {{.*}}void @test_auth()` to match both MachO and ELF or, alternatively, use different check prefixes for function labels on MachO and ELF to avoid regex in match lines. ``` // RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s // RUN: %clang_cc1 -triple aarch64-elf -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s ``` This is probably a subject for another tiny PR since the RUN line is not touched here and the test already existed. https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
@@ -2156,6 +2156,24 @@ static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call) { return Call; } +static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *call) { + if (checkPointerAuthEnabled(S, call)) return ExprError(); + + // We've already performed normal call type-checking. + Expr *arg = call->getArgs()[0]->IgnoreParenImpCasts(); + + // Operand must be an ordinary or UTF-8 string literal. + auto literal = dyn_cast(arg); kovdan01 wrote: ```suggestion const auto *Literal = dyn_cast(arg); ``` https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
@@ -2156,6 +2156,24 @@ static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call) { return Call; } +static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *call) { + if (checkPointerAuthEnabled(S, call)) return ExprError(); + + // We've already performed normal call type-checking. + Expr *arg = call->getArgs()[0]->IgnoreParenImpCasts(); + + // Operand must be an ordinary or UTF-8 string literal. + auto literal = dyn_cast(arg); + if (!literal || literal->getCharByteWidth() != 1) { +S.Diag(arg->getExprLoc(), diag::err_ptrauth_string_not_literal) kovdan01 wrote: This error message looks untested https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
https://github.com/kovdan01 requested changes to this pull request. The changes themself in terms of functionality look OK to me - but I want someone else with deeper understanding of the context to take a look before this gets merged. https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
@@ -12583,6 +12584,12 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, case Builtin::BI__builtin_expect_with_probability: return Visit(E->getArg(0)); + case Builtin::BI__builtin_ptrauth_string_discriminator: { +auto literal = cast(E->getArg(0)->IgnoreParenImpCasts()); kovdan01 wrote: ```suggestion const auto *Literal = cast(E->getArg(0)->IgnoreParenImpCasts()); ``` https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
@@ -2156,6 +2156,24 @@ static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call) { return Call; } +static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *call) { kovdan01 wrote: Naming style of variables all over the function (use `PascalCase` https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly) https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
@@ -2156,6 +2156,24 @@ static ExprResult PointerAuthAuthAndResign(Sema &S, CallExpr *Call) { return Call; } +static ExprResult PointerAuthStringDiscriminator(Sema &S, CallExpr *call) { + if (checkPointerAuthEnabled(S, call)) return ExprError(); + + // We've already performed normal call type-checking. + Expr *arg = call->getArgs()[0]->IgnoreParenImpCasts(); kovdan01 wrote: ```suggestion const Expr *arg = call->getArgs()[0]->IgnoreParenImpCasts(); ``` https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_string_discriminator builtin. (PR #93903)
@@ -12583,6 +12584,12 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, case Builtin::BI__builtin_expect_with_probability: return Visit(E->getArg(0)); + case Builtin::BI__builtin_ptrauth_string_discriminator: { +auto literal = cast(E->getArg(0)->IgnoreParenImpCasts()); +auto result = getPointerAuthStableSipHash16(literal->getString()); kovdan01 wrote: Does `auto` increase readability here? `uint64_t Result` IMHO looks better - at least, with `auto` it's not obvious which type the variable has. https://github.com/llvm/llvm-project/pull/93903 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios -fptrauth-intrinsics -emit-llvm %s -o - | FileCheck %s kovdan01 wrote: > @kovdan01 If you're having a RUN line locally, can you just suggest a change > here? Updated the comment, thanks https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
https://github.com/kovdan01 edited https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [clang] [clang] Define ptrauth_sign_constant builtin. (PR #93904)
@@ -2061,6 +2071,58 @@ ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) { } } +ConstantLValue +ConstantLValueEmitter::emitPointerAuthSignConstant(const CallExpr *E) { + auto unsignedPointer = emitPointerAuthPointer(E->getArg(0)); + auto key = emitPointerAuthKey(E->getArg(1)); + llvm::Constant *storageAddress; + llvm::Constant *otherDiscriminator; + std::tie(storageAddress, otherDiscriminator) = +emitPointerAuthDiscriminator(E->getArg(2)); + + auto signedPointer = +CGM.getConstantSignedPointer(unsignedPointer, key, storageAddress, + otherDiscriminator); + return signedPointer; +} + +llvm::Constant *ConstantLValueEmitter::emitPointerAuthPointer(const Expr *E) { + Expr::EvalResult result; + bool succeeded = E->EvaluateAsRValue(result, CGM.getContext()); + assert(succeeded); (void) succeeded; + + // The assertions here are all checked by Sema. + assert(result.Val.isLValue()); + return ConstantEmitter(CGM, Emitter.CGF) + .emitAbstract(E->getExprLoc(), result.Val, E->getType()); +} + +unsigned ConstantLValueEmitter::emitPointerAuthKey(const Expr *E) { + return E->EvaluateKnownConstInt(CGM.getContext()).getZExtValue(); +} + +std::pair +ConstantLValueEmitter::emitPointerAuthDiscriminator(const Expr *E) { + E = E->IgnoreParens(); + + if (auto call = dyn_cast(E)) { kovdan01 wrote: For `call`, `pointer`, `extra`, `result`: `auto` -> `auto *` https://github.com/llvm/llvm-project/pull/93904 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits