-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] Define ptrauth_string_discriminator builtin. #93903
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[clang] Define ptrauth_string_discriminator builtin. #93903
Conversation
@llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-clang Author: Ahmed Bougacha (ahmedbougacha) ChangesThis exposes the ABI-stable hash function that allows computing a 16-bit discriminator from a constant string. This allows manually matching the implicit string discriminators computed in the ABI (e.g., from mangled names for vtable pointer/entry signing), as well as enabling the use of interesting discriminators when manually annotating specific pointers with the __ptrauth qualifier. Full diff: https://github.com/llvm/llvm-project/pull/93903.diff 7 Files Affected:
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 11982af3fa609..836697632a3bc 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4411,6 +4411,12 @@ def PtrauthAuth : Builtin {
let Prototype = "void*(void*,int,void*)";
}
+def PtrauthStringDiscriminator : Builtin {
+ let Spellings = ["__builtin_ptrauth_string_discriminator"];
+ let Attributes = [NoThrow, Const, Constexpr];
+ let Prototype = "size_t(char const*)";
+}
+
// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions.
// We need the generic prototype, since the packet type could be anything.
def ReadPipe : OCLPipeLangBuiltin {
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f15cba63624ea..64add46248c69 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -928,6 +928,8 @@ def warn_ptrauth_sign_null_pointer :
def warn_ptrauth_auth_null_pointer :
Warning<"authenticating a null pointer will almost certainly trap">,
InGroup<PtrAuthNullPointers>;
+def err_ptrauth_string_not_literal : Error<
+ "argument must be a string literal%select{| of char type}0">;
/// main()
// static main() is not an error in C, just in C++.
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index f1aa19e4409e1..eafecfb5fe5b1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -58,6 +58,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/SaveAndRestore.h"
+#include "llvm/Support/SipHash.h"
#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"
#include <cstring>
@@ -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<StringLiteral>(E->getArg(0)->IgnoreParenImpCasts());
+ auto result = getPointerAuthStableSipHash16(literal->getString());
+ return Success(result, E);
+ }
+
case Builtin::BI__builtin_ffs:
case Builtin::BI__builtin_ffsl:
case Builtin::BI__builtin_ffsll: {
diff --git a/clang/lib/Headers/ptrauth.h b/clang/lib/Headers/ptrauth.h
index 036665d75a91b..3e58af1802084 100644
--- a/clang/lib/Headers/ptrauth.h
+++ b/clang/lib/Headers/ptrauth.h
@@ -135,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.
+
+ The argument must be a string literal.
+ A call to this function is an integer constant expression. */
+#define ptrauth_string_discriminator(__string) \
+ __builtin_ptrauth_string_discriminator(__string)
+
/* Compute a signature for the given pair of pointer-sized values.
The order of the arguments is significant.
@@ -196,6 +207,12 @@ typedef __UINTPTR_TYPE__ ptrauth_generic_signature_t;
__value; \
})
+#define ptrauth_string_discriminator(__string) \
+ ({ \
+ (void)__string; \
+ ((ptrauth_extra_data_t)0); \
+ })
+
#define ptrauth_sign_generic_data(__value, __data) \
({ \
(void)__value; \
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index c3251f3cc9d81..f6012ef4b3601 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -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<StringLiteral>(arg);
+ if (!literal || literal->getCharByteWidth() != 1) {
+ S.Diag(arg->getExprLoc(), diag::err_ptrauth_string_not_literal)
+ << (literal ? 1 : 0)
+ << arg->getSourceRange();
+ return ExprError();
+ }
+
+ return call;
+}
+
static ExprResult BuiltinLaunder(Sema &S, CallExpr *TheCall) {
if (S.checkArgCount(TheCall, 1))
return ExprError();
@@ -2922,6 +2940,8 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
return PointerAuthSignGenericData(*this, TheCall);
case Builtin::BI__builtin_ptrauth_auth_and_resign:
return PointerAuthAuthAndResign(*this, TheCall);
+ case Builtin::BI__builtin_ptrauth_string_discriminator:
+ return PointerAuthStringDiscriminator(*this, TheCall);
// OpenCL v2.0, s6.13.16 - Pipe functions
case Builtin::BIread_pipe:
case Builtin::BIwrite_pipe:
diff --git a/clang/test/CodeGen/ptrauth-intrinsics.c b/clang/test/CodeGen/ptrauth-intrinsics.c
index 17f28dddb3801..d602325da8b17 100644
--- a/clang/test/CodeGen/ptrauth-intrinsics.c
+++ b/clang/test/CodeGen/ptrauth-intrinsics.c
@@ -71,3 +71,16 @@ void test_sign_generic_data() {
// CHECK-NEXT: store i64 [[RESULT]], ptr @signature,
signature = __builtin_ptrauth_sign_generic_data(fnptr, ptr_discriminator);
}
+
+// CHECK-LABEL: define void @test_string_discriminator()
+void test_string_discriminator() {
+ // CHECK: [[X:%.*]] = alloca i32
+
+ // Check a couple of random discriminators used by Swift.
+
+ // CHECK: store i32 58298, ptr [[X]],
+ int x = __builtin_ptrauth_string_discriminator("InitializeWithCopy");
+
+ // CHECK: store i32 9112, ptr [[X]],
+ x = __builtin_ptrauth_string_discriminator("DestroyArray");
+}
diff --git a/clang/test/Sema/ptrauth-intrinsics-macro.c b/clang/test/Sema/ptrauth-intrinsics-macro.c
index 07d6374045145..540f2846b7ce1 100644
--- a/clang/test/Sema/ptrauth-intrinsics-macro.c
+++ b/clang/test/Sema/ptrauth-intrinsics-macro.c
@@ -32,3 +32,8 @@ void test(int *dp, int value) {
int t2 = ptrauth_sign_generic_data(dp, 0);
(void)t2;
}
+
+void test_string_discriminator(int *dp) {
+ ptrauth_extra_data_t t0 = ptrauth_string_discriminator("string");
+ (void)t0;
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See mostly code style nits above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but I want someone else with deeper understanding of the context to take a look before this gets merged.
8e9ab9c
to
bf413d6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
bb44624
to
b0a19c3
Compare
@ahmedbougacha Will you please rebase? |
This exposes the ABI-stable hash function that allows computing a 16-bit discriminator from a constant string. This allows manually matching the implicit string discriminators computed in the ABI (e.g., from mangled names for vtable pointer/entry signing), as well as enabling the use of interesting discriminators when manually annotating specific pointers with the __ptrauth qualifier. Co-Authored-By: John McCall <[email protected]>
- add missing sema test - also test ELF codegen for intrinsics - various capitalization and type nits
- tweaks to header/doc comments - add test for wide string literal
8e7d4bc
to
11e7dcc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
This exposes the ABI-stable hash function that allows computing a 16-bit discriminator from a constant string. This allows manually matching the implicit string discriminators computed in the ABI (e.g., from mangled names for vtable pointer/entry signing), as well as enabling the use of interesting discriminators when manually annotating specific pointers with the __ptrauth qualifier. The argument must be a string literal of char character type. The result has type ptrauth_extra_data_t. The result value is never zero and always within range for both the __ptrauth qualifier and ptrauth_blend_discriminator. This can be used in constant expressions. Co-authored-by: John McCall <[email protected]>
This exposes the ABI-stable hash function that allows computing a 16-bit discriminator from a constant string.
This allows manually matching the implicit string discriminators computed in the ABI (e.g., from mangled names for vtable pointer/entry signing), as well as enabling the use of interesting discriminators when manually annotating specific pointers with the __ptrauth qualifier.