pac.c (e74e1d55728509b352e4eec4283dd5b2781b2070) | pac.c (766d95b1ed93ebdd07ac87490e60e442342f5dc4) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2// Copyright (C) 2020 ARM Limited 3 4#include <sys/auxv.h> 5#include <signal.h> 6#include <setjmp.h> 7 8#include "../../kselftest_harness.h" 9#include "helper.h" 10 | 1// SPDX-License-Identifier: GPL-2.0 2// Copyright (C) 2020 ARM Limited 3 4#include <sys/auxv.h> 5#include <signal.h> 6#include <setjmp.h> 7 8#include "../../kselftest_harness.h" 9#include "helper.h" 10 |
11#define PAC_COLLISION_ATTEMPTS 10 12/* 13 * The kernel sets TBID by default. So bits 55 and above should remain 14 * untouched no matter what. 15 * The VA space size is 48 bits. Bigger is opt-in. 16 */ 17#define PAC_MASK (~0xff80ffffffffffff) |
|
11#define ASSERT_PAUTH_ENABLED() \ 12do { \ 13 unsigned long hwcaps = getauxval(AT_HWCAP); \ 14 /* data key instructions are not in NOP space. This prevents a SIGILL */ \ 15 ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \ 16} while (0) | 18#define ASSERT_PAUTH_ENABLED() \ 19do { \ 20 unsigned long hwcaps = getauxval(AT_HWCAP); \ 21 /* data key instructions are not in NOP space. This prevents a SIGILL */ \ 22 ASSERT_NE(0, hwcaps & HWCAP_PACA) TH_LOG("PAUTH not enabled"); \ 23} while (0) |
24#define ASSERT_GENERIC_PAUTH_ENABLED() \ 25do { \ 26 unsigned long hwcaps = getauxval(AT_HWCAP); \ 27 /* generic key instructions are not in NOP space. This prevents a SIGILL */ \ 28 ASSERT_NE(0, hwcaps & HWCAP_PACG) TH_LOG("Generic PAUTH not enabled"); \ 29} while (0) |
|
17 18sigjmp_buf jmpbuf; 19void pac_signal_handler(int signum, siginfo_t *si, void *uc) 20{ 21 if (signum == SIGSEGV || signum == SIGILL) 22 siglongjmp(jmpbuf, 1); 23} 24 --- 11 unchanged lines hidden (view full) --- 36 sigaction(SIGSEGV, &sa, NULL); 37 sigaction(SIGILL, &sa, NULL); 38 39 pac_corruptor(); 40 ASSERT_TRUE(0) TH_LOG("SIGSEGV/SIGILL signal did not occur"); 41 } 42} 43 | 30 31sigjmp_buf jmpbuf; 32void pac_signal_handler(int signum, siginfo_t *si, void *uc) 33{ 34 if (signum == SIGSEGV || signum == SIGILL) 35 siglongjmp(jmpbuf, 1); 36} 37 --- 11 unchanged lines hidden (view full) --- 49 sigaction(SIGSEGV, &sa, NULL); 50 sigaction(SIGILL, &sa, NULL); 51 52 pac_corruptor(); 53 ASSERT_TRUE(0) TH_LOG("SIGSEGV/SIGILL signal did not occur"); 54 } 55} 56 |
57/* 58 * There are no separate pac* and aut* controls so checking only the pac* 59 * instructions is sufficient 60 */ 61TEST(pac_instructions_not_nop) 62{ 63 size_t keyia = 0; 64 size_t keyib = 0; 65 size_t keyda = 0; 66 size_t keydb = 0; 67 68 ASSERT_PAUTH_ENABLED(); 69 70 for (int i = 0; i < PAC_COLLISION_ATTEMPTS; i++) { 71 keyia |= keyia_sign(i) & PAC_MASK; 72 keyib |= keyib_sign(i) & PAC_MASK; 73 keyda |= keyda_sign(i) & PAC_MASK; 74 keydb |= keydb_sign(i) & PAC_MASK; 75 } 76 77 ASSERT_NE(0, keyia) TH_LOG("keyia instructions did nothing"); 78 ASSERT_NE(0, keyib) TH_LOG("keyib instructions did nothing"); 79 ASSERT_NE(0, keyda) TH_LOG("keyda instructions did nothing"); 80 ASSERT_NE(0, keydb) TH_LOG("keydb instructions did nothing"); 81} 82 83TEST(pac_instructions_not_nop_generic) 84{ 85 size_t keyg = 0; 86 87 ASSERT_GENERIC_PAUTH_ENABLED(); 88 89 for (int i = 0; i < PAC_COLLISION_ATTEMPTS; i++) 90 keyg |= keyg_sign(i) & PAC_MASK; 91 92 ASSERT_NE(0, keyg) TH_LOG("keyg instructions did nothing"); 93} 94 |
|
44TEST_HARNESS_MAIN | 95TEST_HARNESS_MAIN |