mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
sys_poll: fix incorrect type for 'timeout' parameter
The 'poll()' system call timeout parameter is supposed to be 'int', not 'long'. Now, the reason this matters is that right now 32-bit compat mode is broken on at least x86-64, because the 32-bit code just calls 'sys_poll()' directly on x86-64, and the 32-bit argument will have been zero-extended, turning a signed 'int' into a large unsigned 'long' value. We could just introduce a 'compat_sys_poll()' function for this, and that may eventually be what we have to do, but since the actual standard poll() semantics is *supposed* to be 'int', and since at least on x86-64 glibc sign-extends the argument before invocing the system call (so nobody can actually use a 64-bit timeout value in user space _anyway_, even in 64-bit binaries), the simpler solution would seem to be to just fix the definition of the system call to match what it should have been from the very start. If it turns out that somebody somehow circumvents the user-level libc 64-bit sign extension and actually uses a large unsigned 64-bit timeout despite that not being how poll() is supposed to work, we will need to do the compat_sys_poll() approach. Reported-by: Thomas Meyer <thomas@m3y3r.de> Acked-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
797a796a13
commit
faf309009e
@ -662,7 +662,7 @@ ENTRY(sys32_getresuid16_wrapper)
|
||||
ENTRY(sys32_poll_wrapper)
|
||||
llgtr %r2,%r2 # struct pollfd *
|
||||
llgfr %r3,%r3 # unsigned int
|
||||
lgfr %r4,%r4 # long
|
||||
lgfr %r4,%r4 # int
|
||||
jg sys_poll # branch to system call
|
||||
|
||||
ENTRY(sys32_setresgid16_wrapper)
|
||||
|
@ -912,7 +912,7 @@ static long do_restart_poll(struct restart_block *restart_block)
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
|
||||
long, timeout_msecs)
|
||||
int, timeout_msecs)
|
||||
{
|
||||
struct timespec end_time, *to = NULL;
|
||||
int ret;
|
||||
|
@ -624,7 +624,7 @@ asmlinkage long sys_socketpair(int, int, int, int __user *);
|
||||
asmlinkage long sys_socketcall(int call, unsigned long __user *args);
|
||||
asmlinkage long sys_listen(int, int);
|
||||
asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
|
||||
long timeout);
|
||||
int timeout);
|
||||
asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
|
||||
fd_set __user *exp, struct timeval __user *tvp);
|
||||
asmlinkage long sys_old_select(struct sel_arg_struct __user *arg);
|
||||
|
Loading…
Reference in New Issue
Block a user