lib/syscall: fix syscall registers retrieval on 32-bit platforms
authorWilly Tarreau <w@1wt.eu>
Mon, 30 Nov 2020 07:36:48 +0000 (08:36 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 11 Dec 2020 12:22:11 +0000 (13:22 +0100)
commitbc6ca732f4a4dce79abd0fdeb81fc5c20e01fd0a
treefe20a05d364e96981ba40593ef5b88b45ef200b1
parent67dc2e5d2ec59da26581b27bacecc02db7b40858
lib/syscall: fix syscall registers retrieval on 32-bit platforms

commit 4f134b89a24b965991e7c345b9a4591821f7c2a6 upstream.

Lilith >_> and Claudio Bozzato of Cisco Talos security team reported
that collect_syscall() improperly casts the syscall registers to 64-bit
values leaking the uninitialized last 24 bytes on 32-bit platforms, that
are visible in /proc/self/syscall.

The cause is that info->data.args are u64 while syscall_get_arguments()
uses longs, as hinted by the bogus pointer cast in the function.

Let's just proceed like the other call places, by retrieving the
registers into an array of longs before assigning them to the caller's
array.  This was successfully tested on x86_64, i386 and ppc32.

Reference: CVE-2020-28588, TALOS-2020-1211
Fixes: 631b7abacd02 ("ptrace: Remove maxargs from task_current_syscall()")
Cc: Greg KH <greg@kroah.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Tested-by: Michael Ellerman <mpe@ellerman.id.au> (ppc32)
Signed-off-by: Willy Tarreau <w@1wt.eu>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
lib/syscall.c