1 #include <stdint.h> 2 #include <assert.h> 3 #include <stdio.h> 4 #include <stdlib.h> 5 6 #define TESTS 1000 7 8 int main() 9 { 10 int i, count = 0; 11 float perc; 12 void *base = malloc(TESTS); 13 14 for (i = 0; i < TESTS; i++) { 15 uintptr_t in, x, y; 16 17 in = i + (uintptr_t) base; 18 19 asm("mov %0, %[in]\n\t" 20 "pacia %0, sp\n\t" /* sigill if pauth not supported */ 21 "eor %0, %0, #4\n\t" /* corrupt single bit */ 22 "mov %1, %0\n\t" 23 "autia %1, sp\n\t" /* validate corrupted pointer */ 24 "xpaci %0\n\t" /* strip pac from corrupted pointer */ 25 : /* out */ "=r"(x), "=r"(y) 26 : /* in */ [in] "r" (in) 27 : /* clobbers */); 28 29 /* 30 * Once stripped, the corrupted pointer is of the form 0x0000...wxyz. 31 * We expect the autia to indicate failure, producing a pointer of the 32 * form 0x000e....wxyz. Use xpaci and != for the test, rather than 33 * extracting explicit bits from the top, because the location of the 34 * error code "e" depends on the configuration of virtual memory. 35 */ 36 if (x != y) { 37 count++; 38 } 39 40 } 41 perc = (float) count / (float) TESTS; 42 printf("Checks Passed: %0.2f%%", perc * 100.0); 43 assert(perc > 0.95); 44 return 0; 45 } 46