https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84066
Bug ID: 84066
Summary: Wrong shadow stack register size is saved for x32
Product: gcc
Version: 8.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: hjl.tools at gmail dot com
CC: igor.v.tsimbalist at intel dot com
Blocks: 81652
Target Milestone: ---
Target: x86-64
x32 is a 64-bit process with 32-bit software pointer and kernel may
place x32 shadow stack above 4GB. We need to save and restore 64-bit
shadow stack register for x32:
[hjl@gnu-tools-1 tmp]$ cat x.c
void *buf[5];
int execute(void)
{
if (__builtin_setjmp (buf) == 0)
return 0;
else
return 1;
}
[hjl@gnu-tools-1 tmp]$ /usr/gcc-8.0.0-x32/bin/gcc -O2 -fcf-protection -mcet x.c
-S -mx32
[hjl@gnu-tools-1 tmp]$ cat x.s
.file "x.c"
.text
.p2align 4,,15
.globl execute
.type execute, @function
execute:
.LFB0:
.cfi_startproc
endbr64
.L2:
endbr64
xorl %eax, %eax
movl %esp, buf(%rip)
movl $.L2, buf+4(%rip)
movl %esp, buf+8(%rip)
rdsspd %eax <<<<<<<<<< Only 32-bit shadow stack register is saved.
movl %eax, buf+12(%rip)
xorl %eax, %eax
ret
.cfi_endproc
.LFE0:
.size execute, .-execute
.comm buf,20,16
Since builtin jmp buf size is 5 pointers. We have space to save 64-bit
shadow stack pointers: 32-bit SP, 32-bit FP, 32-bit IP, 64-bit SSP.
Referenced Bugs:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81652
[Bug 81652] [meta-bug] -fcf-protection=full -mcet bugs