Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

x86: fix error handling for 32-bit compat out-of-range system call numbers

Commit 3f5159a9221f ("x86/asm/entry/32: Update -ENOSYS handling to match
the 64-bit logic") broke the ENOSYS handling for the 32-bit compat case.
The proper error return value was never loaded into %rax, except if
things just happened to go through the audit paths, which ended up
reloading the return value.

This moves the loading or %rax into the normal system call path, just to
make sure the error case triggers it. It's kind of sad, since it adds a
useless instruction to reload the register to the fast path, but it's
not like that single load from the stack is going to be noticeable.

Reported-by: David Drysdale <drysdale@google.com>
Tested-by: Kees Cook <keescook@chromium.org>
Acked-by: Andy Lutomirski <luto@amacapital.net>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

+2 -1
+2 -1
arch/x86/entry/entry_64_compat.S
··· 140 140 */ 141 141 andl $~TS_COMPAT, ASM_THREAD_INFO(TI_status, %rsp, SIZEOF_PTREGS) 142 142 movl RIP(%rsp), %ecx /* User %eip */ 143 + movq RAX(%rsp), %rax 143 144 RESTORE_RSI_RDI 144 145 xorl %edx, %edx /* Do not leak kernel information */ 145 146 xorq %r8, %r8 ··· 220 219 1: setbe %al /* 1 if error, 0 if not */ 221 220 movzbl %al, %edi /* zero-extend that into %edi */ 222 221 call __audit_syscall_exit 223 - movq RAX(%rsp), %rax /* reload syscall return value */ 224 222 movl $(_TIF_ALLWORK_MASK & ~_TIF_SYSCALL_AUDIT), %edi 225 223 DISABLE_INTERRUPTS(CLBR_NONE) 226 224 TRACE_IRQS_OFF ··· 368 368 RESTORE_RSI_RDI_RDX 369 369 movl RIP(%rsp), %ecx 370 370 movl EFLAGS(%rsp), %r11d 371 + movq RAX(%rsp), %rax 371 372 xorq %r10, %r10 372 373 xorq %r9, %r9 373 374 xorq %r8, %r8