xref: /llvm-project/clang/test/Sema/ptrauth.c (revision ae1c564d1522f1202d05b698dce8d9c8ca46667c)
1 // RUN: %clang_cc1 -triple arm64-apple-ios -fsyntax-only -verify -fptrauth-intrinsics %s -fexperimental-new-constant-interpreter
2 
3 #if __has_feature(ptrauth_intrinsics)
4 #warning Pointer authentication enabled!
5 // expected-warning@-1 {{Pointer authentication enabled!}}
6 #endif
7 
8 #if __aarch64__
9 #define VALID_CODE_KEY 0
10 #define VALID_DATA_KEY 2
11 #define INVALID_KEY 200
12 #else
13 #error Provide these constants if you port this test
14 #endif
15 
16 #define NULL ((void*) 0)
17 struct A { int x; } mismatched_type;
18 
19 extern int dv;
20 extern int fv(int);
21 
test_strip(int * dp,int (* fp)(int))22 void test_strip(int *dp, int (*fp)(int)) {
23   __builtin_ptrauth_strip(dp); // expected-error {{too few arguments}}
24   __builtin_ptrauth_strip(dp, VALID_DATA_KEY, dp); // expected-error {{too many arguments}}
25   (void) __builtin_ptrauth_strip(NULL, VALID_DATA_KEY); // no warning
26 
27   __builtin_ptrauth_strip(mismatched_type, VALID_DATA_KEY); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
28   __builtin_ptrauth_strip(dp, mismatched_type); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
29 
30   int *dr = __builtin_ptrauth_strip(dp, VALID_DATA_KEY);
31   dr = __builtin_ptrauth_strip(dp, INVALID_KEY); // expected-error {{does not identify a valid pointer authentication key for the current target}}
32 
33   int (*fr)(int) = __builtin_ptrauth_strip(fp, VALID_CODE_KEY);
34   fr = __builtin_ptrauth_strip(fp, INVALID_KEY); // expected-error {{does not identify a valid pointer authentication key for the current target}}
35 
36   float *mismatch = __builtin_ptrauth_strip(dp, VALID_DATA_KEY); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
37 }
38 
test_blend_discriminator(int * dp,int (* fp)(int),int value)39 void test_blend_discriminator(int *dp, int (*fp)(int), int value) {
40   __builtin_ptrauth_blend_discriminator(dp); // expected-error {{too few arguments}}
41   __builtin_ptrauth_blend_discriminator(dp, dp, dp); // expected-error {{too many arguments}}
42   (void) __builtin_ptrauth_blend_discriminator(dp, value); // no warning
43 
44   __builtin_ptrauth_blend_discriminator(mismatched_type, value); // expected-error {{blended pointer must have pointer type; type here is 'struct A'}}
45   __builtin_ptrauth_blend_discriminator(dp, mismatched_type); // expected-error {{blended integer must have integer type; type here is 'struct A'}}
46 
47   float *mismatch = __builtin_ptrauth_blend_discriminator(dp, value); // expected-error {{incompatible integer to pointer conversion initializing 'float *' with an expression of type}}
48 }
49 
test_string_discriminator(const char * str)50 void test_string_discriminator(const char *str) {
51   __builtin_ptrauth_string_discriminator(); // expected-error {{too few arguments}}
52   __builtin_ptrauth_string_discriminator(str, str); // expected-error {{too many arguments}}
53   (void) __builtin_ptrauth_string_discriminator("test string"); // no warning
54 
55   __builtin_ptrauth_string_discriminator(str); // expected-error {{argument must be a string literal}}
56   __builtin_ptrauth_string_discriminator(L"wide test"); // expected-error {{argument must be a string literal}} expected-warning {{incompatible pointer types passing 'int[10]' to parameter of type 'const char *'}}
57 
58   void *mismatch = __builtin_ptrauth_string_discriminator("test string"); // expected-error {{incompatible integer to pointer conversion initializing 'void *' with an expression of type 'unsigned long'}}
59 }
60 
61 
test_sign_unauthenticated(int * dp,int (* fp)(int))62 void test_sign_unauthenticated(int *dp, int (*fp)(int)) {
63   __builtin_ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY); // expected-error {{too few arguments}}
64   __builtin_ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY, dp, dp); // expected-error {{too many arguments}}
65 
66   __builtin_ptrauth_sign_unauthenticated(mismatched_type, VALID_DATA_KEY, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
67   __builtin_ptrauth_sign_unauthenticated(dp, mismatched_type, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
68   __builtin_ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY, mismatched_type); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
69 
70   (void) __builtin_ptrauth_sign_unauthenticated(NULL, VALID_DATA_KEY, 0); // expected-warning {{signing a null pointer will yield a non-null pointer}}
71 
72   int *dr = __builtin_ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY, 0);
73   dr = __builtin_ptrauth_sign_unauthenticated(dp, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
74 
75   int (*fr)(int) = __builtin_ptrauth_sign_unauthenticated(fp, VALID_CODE_KEY, 0);
76   fr = __builtin_ptrauth_sign_unauthenticated(fp, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
77 
78   float *mismatch = __builtin_ptrauth_sign_unauthenticated(dp, VALID_DATA_KEY, 0); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
79 }
80 
test_auth(int * dp,int (* fp)(int))81 void test_auth(int *dp, int (*fp)(int)) {
82   __builtin_ptrauth_auth(dp, VALID_DATA_KEY); // expected-error {{too few arguments}}
83   __builtin_ptrauth_auth(dp, VALID_DATA_KEY, dp, dp); // expected-error {{too many arguments}}
84 
85   __builtin_ptrauth_auth(mismatched_type, VALID_DATA_KEY, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
86   __builtin_ptrauth_auth(dp, mismatched_type, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
87   __builtin_ptrauth_auth(dp, VALID_DATA_KEY, mismatched_type); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
88 
89   (void) __builtin_ptrauth_auth(NULL, VALID_DATA_KEY, 0); // expected-warning {{authenticating a null pointer will almost certainly trap}}
90 
91   int *dr = __builtin_ptrauth_auth(dp, VALID_DATA_KEY, 0);
92   dr = __builtin_ptrauth_auth(dp, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
93 
94   int (*fr)(int) = __builtin_ptrauth_auth(fp, VALID_CODE_KEY, 0);
95   fr = __builtin_ptrauth_auth(fp, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
96 
97   float *mismatch = __builtin_ptrauth_auth(dp, VALID_DATA_KEY, 0); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
98 }
99 
test_auth_and_resign(int * dp,int (* fp)(int))100 void test_auth_and_resign(int *dp, int (*fp)(int)) {
101   __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, VALID_DATA_KEY); // expected-error {{too few arguments}}
102   __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, dp, VALID_DATA_KEY, dp, 0); // expected-error {{too many arguments}}
103 
104   __builtin_ptrauth_auth_and_resign(mismatched_type, VALID_DATA_KEY, 0, VALID_DATA_KEY, dp); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
105   __builtin_ptrauth_auth_and_resign(dp, mismatched_type, 0, VALID_DATA_KEY, dp); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
106   __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, mismatched_type, VALID_DATA_KEY, dp); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
107   __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, mismatched_type, dp); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
108   __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, VALID_DATA_KEY, mismatched_type); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
109 
110   (void) __builtin_ptrauth_auth_and_resign(NULL, VALID_DATA_KEY, 0, VALID_DATA_KEY, dp); // expected-warning {{authenticating a null pointer will almost certainly trap}}
111 
112   int *dr = __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, VALID_DATA_KEY, dp);
113   dr = __builtin_ptrauth_auth_and_resign(dp, INVALID_KEY, 0, VALID_DATA_KEY, dp); // expected-error {{does not identify a valid pointer authentication key for the current target}}
114   dr = __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, INVALID_KEY, dp); // expected-error {{does not identify a valid pointer authentication key for the current target}}
115 
116   int (*fr)(int) = __builtin_ptrauth_auth_and_resign(fp, VALID_CODE_KEY, 0, VALID_CODE_KEY, dp);
117   fr = __builtin_ptrauth_auth_and_resign(fp, INVALID_KEY, 0, VALID_CODE_KEY, dp); // expected-error {{does not identify a valid pointer authentication key for the current target}}
118   fr = __builtin_ptrauth_auth_and_resign(fp, VALID_CODE_KEY, 0, INVALID_KEY, dp); // expected-error {{does not identify a valid pointer authentication key for the current target}}
119 
120   float *mismatch = __builtin_ptrauth_auth_and_resign(dp, VALID_DATA_KEY, 0, VALID_DATA_KEY, dp); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
121 }
122 
test_sign_generic_data(int * dp)123 void test_sign_generic_data(int *dp) {
124   __builtin_ptrauth_sign_generic_data(dp); // expected-error {{too few arguments}}
125   __builtin_ptrauth_sign_generic_data(dp, 0, 0); // expected-error {{too many arguments}}
126 
127   __builtin_ptrauth_sign_generic_data(mismatched_type, 0); // expected-error {{signed value must have pointer or integer type; type here is 'struct A'}}
128   __builtin_ptrauth_sign_generic_data(dp, mismatched_type); // expected-error {{extra discriminator must have pointer or integer type; type here is 'struct A'}}
129 
130   (void) __builtin_ptrauth_sign_generic_data(NULL, 0); // no warning
131 
132   unsigned long dr = __builtin_ptrauth_sign_generic_data(dp, 0);
133   dr = __builtin_ptrauth_sign_generic_data(dp, &dv);
134   dr = __builtin_ptrauth_sign_generic_data(12314, 0);
135   dr = __builtin_ptrauth_sign_generic_data(12314, &dv);
136 
137   int *mismatch = __builtin_ptrauth_sign_generic_data(dp, 0); // expected-error {{incompatible integer to pointer conversion initializing 'int *' with an expression of type}}
138 }
139 
140 
141 typedef int (*fp_t)(int);
142 
143 static int dv_weakref __attribute__((weakref("dv")));
144 extern int dv_weak __attribute__((weak));
145 
146 int *t_cst_sig1 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY); // expected-error {{too few arguments}}
147 int *t_cst_sig2 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, &dv, &dv); // expected-error {{too many arguments}}
148 
149 int *t_cst_sig3 = __builtin_ptrauth_sign_constant(mismatched_type, VALID_DATA_KEY, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
150 int *t_cst_sig4 = __builtin_ptrauth_sign_constant(&dv, mismatched_type, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
151 int *t_cst_sig5 = __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'}}
152 
153 float *t_cst_result = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, 0); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
154 
155 int *t_cst_valid1 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, 0);
156 int *t_cst_valid2 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, __builtin_ptrauth_blend_discriminator(&dv, 0));
157 int *t_cst_valid3 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, __builtin_ptrauth_blend_discriminator(&dv + 8, 0));
158 int *t_cst_valid4 = __builtin_ptrauth_sign_constant(&dv_weak, VALID_DATA_KEY, 0);
159 int *t_cst_valid5 = __builtin_ptrauth_sign_constant(&dv_weakref, VALID_DATA_KEY, 0);
160 
161 int *t_cst_ptr = __builtin_ptrauth_sign_constant(NULL, VALID_DATA_KEY, &dv); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
162 int *t_cst_key = __builtin_ptrauth_sign_constant(&dv, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
163 int *t_cst_disc1 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, &fv); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
164 int *t_cst_disc2 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, __builtin_ptrauth_blend_discriminator(&fv, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
165 
166 fp_t t_cst_f_valid1 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, 0);
167 fp_t t_cst_f_valid2 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, __builtin_ptrauth_blend_discriminator(&dv, 0));
168 fp_t t_cst_f_valid3 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, __builtin_ptrauth_blend_discriminator(&dv + 8, 0));
169 
170 fp_t t_cst_f_key = __builtin_ptrauth_sign_constant(&fv, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
171 fp_t t_cst_f_disc1 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, &fv); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
172 fp_t t_cst_f_disc2 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, __builtin_ptrauth_blend_discriminator(&fv, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
173 
174 int *t_cst_offset = __builtin_ptrauth_sign_constant((int *)((char*)&dv + 16), VALID_DATA_KEY, 0);
175 fp_t t_cst_f_offset = __builtin_ptrauth_sign_constant((int (*)(int))((char*)&fv + 16), VALID_CODE_KEY, 0); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
176 
test_sign_constant(int * dp,fp_t fp)177 void test_sign_constant(int *dp, fp_t fp) {
178   int *sig1 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY); // expected-error {{too few arguments}}
179   int *sig2 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, &dv, &dv); // expected-error {{too many arguments}}
180 
181   int *sig3 = __builtin_ptrauth_sign_constant(mismatched_type, VALID_DATA_KEY, 0); // expected-error {{signed value must have pointer type; type here is 'struct A'}}
182   int *sig4 = __builtin_ptrauth_sign_constant(&dv, mismatched_type, 0); // expected-error {{passing 'struct A' to parameter of incompatible type 'int'}}
183   int *sig5 = __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'}}
184 
185   float *result = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, 0); // expected-warning {{incompatible pointer types initializing 'float *' with an expression of type 'int *'}}
186 
187   int *valid1 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, 0);
188   int *valid2 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, __builtin_ptrauth_blend_discriminator(&dv, 0));
189   int *valid3 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, __builtin_ptrauth_blend_discriminator(&dv + 8, 0));
190   int *valid4 = __builtin_ptrauth_sign_constant(&dv_weak, VALID_DATA_KEY, 0);
191   int *valid5 = __builtin_ptrauth_sign_constant(&dv_weakref, VALID_DATA_KEY, 0);
192 
193   int *ptr = __builtin_ptrauth_sign_constant(NULL, VALID_DATA_KEY, &dv); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
194   int *key = __builtin_ptrauth_sign_constant(&dv, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
195   int *disc1 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, &fv); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
196   int *disc2 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, __builtin_ptrauth_blend_discriminator(&fv, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
197 
198   int *ptr2 = __builtin_ptrauth_sign_constant(dp, VALID_DATA_KEY, 0); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
199   int *disc3 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, dp); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
200   int *disc4 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, __builtin_ptrauth_blend_discriminator(dp, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
201   int *disc5 = __builtin_ptrauth_sign_constant(&dv, VALID_DATA_KEY, __builtin_ptrauth_blend_discriminator(&dv, *dp)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
202 
203   fp_t f_valid1 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, 0);
204   fp_t f_valid2 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, __builtin_ptrauth_blend_discriminator(&dv, 0));
205   fp_t f_valid3 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, __builtin_ptrauth_blend_discriminator(&dv + 8, 0));
206 
207   fp_t f_key = __builtin_ptrauth_sign_constant(&fv, INVALID_KEY, 0); // expected-error {{does not identify a valid pointer authentication key for the current target}}
208   fp_t f_disc1 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, &fv); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
209   fp_t f_disc2 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, __builtin_ptrauth_blend_discriminator(&fv, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
210 
211   fp_t f_ptr = __builtin_ptrauth_sign_constant(fp, VALID_CODE_KEY, 0); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
212   fp_t f_disc3 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, dp); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
213 
214   fp_t f_disc4 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, __builtin_ptrauth_blend_discriminator(dp, 0)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
215   fp_t f_disc5 = __builtin_ptrauth_sign_constant(&fv, VALID_CODE_KEY, __builtin_ptrauth_blend_discriminator(&dv, *dp)); // expected-error {{discriminator argument to ptrauth_sign_constant must be a constant integer, the address of the global variable where the result will be stored, or a blend of the two}}
216 
217   int *offset = __builtin_ptrauth_sign_constant((int *)((char*)&dv + 16), VALID_DATA_KEY, 0);
218   fp_t f_offset = __builtin_ptrauth_sign_constant((fp_t)((char*)&fv + 16), VALID_CODE_KEY, 0); // expected-error {{argument to ptrauth_sign_constant must refer to a global variable or function}}
219 }
220