Skip to content

Commit 6cb6982

Browse files
amitdanielkachhapctmarinas
authored andcommitted
lkdtm: arm64: test kernel pointer authentication
This test is specific for arm64. When in-kernel Pointer Authentication config is enabled, the return address stored in the stack is signed. This feature helps in ROP kind of attack. If any parameters used to generate the pac (<key, sp, lr>) is modified then this will fail in the authentication stage and will lead to abort. This test changes the input parameter APIA kernel keys to cause abort. The pac computed from the new key can be same as last due to hash collision so this is retried for few times as there is no reliable way to compare the pacs. Even though this test may fail even after retries but this may cause authentication failure at a later stage in earlier function returns. This test can be invoked as, echo CORRUPT_PAC > /sys/kernel/debug/provoke-crash/DIRECT or as below if inserted as a module, insmod lkdtm.ko cpoint_name=DIRECT cpoint_type=CORRUPT_PAC cpoint_count=1 [ 13.118166] lkdtm: Performing direct entry CORRUPT_PAC [ 13.118298] lkdtm: Clearing PAC from the return address [ 13.118466] Unable to handle kernel paging request at virtual address bfff8000108648ec [ 13.118626] Mem abort info: [ 13.118666] ESR = 0x86000004 [ 13.118866] EC = 0x21: IABT (current EL), IL = 32 bits [ 13.118966] SET = 0, FnV = 0 [ 13.119117] EA = 0, S1PTW = 0 Signed-off-by: Amit Daniel Kachhap <[email protected]> Acked-by: Catalin Marinas <[email protected]> Cc: Kees Cook <[email protected]> Signed-off-by: Catalin Marinas <[email protected]>
1 parent 74afda4 commit 6cb6982

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

drivers/misc/lkdtm/bugs.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,39 @@ void lkdtm_DOUBLE_FAULT(void)
378378
pr_err("XFAIL: this test is ia32-only\n");
379379
#endif
380380
}
381+
382+
#ifdef CONFIG_ARM64_PTR_AUTH
383+
static noinline void change_pac_parameters(void)
384+
{
385+
/* Reset the keys of current task */
386+
ptrauth_thread_init_kernel(current);
387+
ptrauth_thread_switch_kernel(current);
388+
}
389+
390+
#define CORRUPT_PAC_ITERATE 10
391+
noinline void lkdtm_CORRUPT_PAC(void)
392+
{
393+
int i;
394+
395+
if (!system_supports_address_auth()) {
396+
pr_err("FAIL: arm64 pointer authentication feature not present\n");
397+
return;
398+
}
399+
400+
pr_info("Change the PAC parameters to force function return failure\n");
401+
/*
402+
* Pac is a hash value computed from input keys, return address and
403+
* stack pointer. As pac has fewer bits so there is a chance of
404+
* collision, so iterate few times to reduce the collision probability.
405+
*/
406+
for (i = 0; i < CORRUPT_PAC_ITERATE; i++)
407+
change_pac_parameters();
408+
409+
pr_err("FAIL: %s test failed. Kernel may be unstable from here\n", __func__);
410+
}
411+
#else /* !CONFIG_ARM64_PTR_AUTH */
412+
noinline void lkdtm_CORRUPT_PAC(void)
413+
{
414+
pr_err("FAIL: arm64 pointer authentication config disabled\n");
415+
}
416+
#endif

drivers/misc/lkdtm/core.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ static const struct crashtype crashtypes[] = {
116116
CRASHTYPE(STACK_GUARD_PAGE_LEADING),
117117
CRASHTYPE(STACK_GUARD_PAGE_TRAILING),
118118
CRASHTYPE(UNSET_SMEP),
119+
CRASHTYPE(CORRUPT_PAC),
119120
CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
120121
CRASHTYPE(OVERWRITE_ALLOCATION),
121122
CRASHTYPE(WRITE_AFTER_FREE),

drivers/misc/lkdtm/lkdtm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ void lkdtm_UNSET_SMEP(void);
3131
#ifdef CONFIG_X86_32
3232
void lkdtm_DOUBLE_FAULT(void);
3333
#endif
34+
void lkdtm_CORRUPT_PAC(void);
3435

3536
/* lkdtm_heap.c */
3637
void __init lkdtm_heap_init(void);

0 commit comments

Comments
 (0)