x86_64/traps.S: fix UBSAN crash when kernel except

The System V AMD64 ABI requires the stack pointer (%rsp) to be 16-byte
aligned immediately before a `call` instruction. In `kernel_exception`,
pushing three 8-byte control registers (%cr2, %cr3, %cr4) after
`INT_SAVE_STATE` misaligned the stack prior to calling
`handleKernelException`.

This commit adds an 8-byte padding before pushing the control registers
to maintain 16-byte alignment.

Previously, compiling the kernel with LLVM and UBSAN enabled resulted in
a recursive exception loop if a UB was encountered elsewhere in kernel
code. The misaligned stack would trigger UBSAN during exception
printing, causing an exception within the exception handler that
looped infinitely.

Signed-off-by: Bill Nguyen <bill.nguyen@unsw.edu.au>
This commit is contained in:
Bill Nguyen 2026-05-19 13:33:40 +10:00 committed by Indan Zupancic
parent b050e4b78d
commit f0535f9e18

View file

@ -568,6 +568,11 @@ BEGIN_FUNC(kernel_exception)
movq 24(%r8), %r8 # RFLAGS
# handleKernelException(vector, errorcode, RIP, RSP, RFLAGS, CR0, CR2, CR3, CR4)
movq %cr0, %r9
# At this point the stack would be 16-bytes aligned, but we are only pushing 3x 8-byte
# values below, so we need to maintain stack alignment.
subq $8, %rsp
movq %cr4, %r11
push %r11
movq %cr3, %r11
@ -575,7 +580,7 @@ BEGIN_FUNC(kernel_exception)
movq %cr2, %r11
push %r11
call handleKernelException
addq $24, %rsp
addq $32, %rsp
# Set RIP in the saved register context to the new IP returned from handleKernelException
LOAD_IRQ_STACK(r8)
movq %rax, 8(%r8)