summaryrefslogtreecommitdiffstats
path: root/include/linux
diff options
context:
space:
mode:
authorRichard Palethorpe <rpalethorpe@suse.com>2024-01-10 15:01:22 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-02-23 08:12:43 +0100
commitd20c05fc2f18651d19ef881d403a0ccf8ce8b8e1 (patch)
tree466ce243640f9c00dbb1e17a4c85442d3b9dc348 /include/linux
parent7c0fdf4485c7bb02a1c7d7a4a68c3686d6ac5d53 (diff)
downloadlinux-stable-d20c05fc2f18651d19ef881d403a0ccf8ce8b8e1.tar.gz
linux-stable-d20c05fc2f18651d19ef881d403a0ccf8ce8b8e1.tar.bz2
linux-stable-d20c05fc2f18651d19ef881d403a0ccf8ce8b8e1.zip
x86/entry/ia32: Ensure s32 is sign extended to s64
commit 56062d60f117dccfb5281869e0ab61e090baf864 upstream. Presently ia32 registers stored in ptregs are unconditionally cast to unsigned int by the ia32 stub. They are then cast to long when passed to __se_sys*, but will not be sign extended. This takes the sign of the syscall argument into account in the ia32 stub. It still casts to unsigned int to avoid implementation specific behavior. However then casts to int or unsigned int as necessary. So that the following cast to long sign extends the value. This fixes the io_pgetevents02 LTP test when compiled with -m32. Presently the systemcall io_pgetevents_time64() unexpectedly accepts -1 for the maximum number of events. It doesn't appear other systemcalls with signed arguments are effected because they all have compat variants defined and wired up. Fixes: ebeb8c82ffaf ("syscalls/x86: Use 'struct pt_regs' based syscall calling for IA32_EMULATION and x32") Suggested-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com> Signed-off-by: Nikolay Borisov <nik.borisov@suse.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Arnd Bergmann <arnd@arndb.de> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20240110130122.3836513-1-nik.borisov@suse.com Link: https://lore.kernel.org/ltp/20210921130127.24131-1-rpalethorpe@suse.com/ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/syscalls.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 2ff814c92f7f..bbe89b1cbf63 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -120,6 +120,7 @@ union bpf_attr;
#define __TYPE_IS_LL(t) (__TYPE_AS(t, 0LL) || __TYPE_AS(t, 0ULL))
#define __SC_LONG(t, a) __typeof(__builtin_choose_expr(__TYPE_IS_LL(t), 0LL, 0L)) a
#define __SC_CAST(t, a) (__force t) a
+#define __SC_TYPE(t, a) t
#define __SC_ARGS(t, a) a
#define __SC_TEST(t, a) (void)BUILD_BUG_ON_ZERO(!__TYPE_IS_LL(t) && sizeof(t) > sizeof(long))