From: Mathias Krause The CET shadow stack test has certain assumptions about the code, namely that it was compiled with frame pointers enabled and the return address won't be 0xdeaddead. Make the code less fragile by actually lifting these assumptions to (1) explicitly mention the dependency to the frame pointer by making us of __builtin_frame_address(0) and (2) modify the return address by toggling bits instead of writing a fixed value. Also ensure that write will actually be generated by the compiler by making it a 'volatile' write. Signed-off-by: Mathias Krause Signed-off-by: Sean Christopherson --- x86/cet.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x86/cet.c b/x86/cet.c index 80864fb1..61059ef2 100644 --- a/x86/cet.c +++ b/x86/cet.c @@ -10,14 +10,14 @@ static uint64_t cet_shstk_func(void) { - unsigned long *ret_addr, *ssp; + unsigned long *ret_addr = __builtin_frame_address(0) + sizeof(void *); + unsigned long *ssp; /* rdsspq %rax */ asm volatile (".byte 0xf3, 0x48, 0x0f, 0x1e, 0xc8" : "=a"(ssp)); - asm("movq %%rbp,%0" : "=r"(ret_addr)); printf("The return-address in shadow-stack = 0x%lx, in normal stack = 0x%lx\n", - *ssp, *(ret_addr + 1)); + *ssp, *ret_addr); /* * In below line, it modifies the return address, it'll trigger #CP @@ -26,7 +26,7 @@ static uint64_t cet_shstk_func(void) * when HW detects the violation. */ printf("Try to temper the return-address, this causes #CP on returning...\n"); - *(ret_addr + 1) = 0xdeaddead; + *(volatile unsigned long *)ret_addr ^= 0xdeaddead; return 0; } -- 2.52.0.rc1.455.g30608eb744-goog