[PATCH] select: time comparison fixes
Andrew Morton [Fri, 17 Feb 2006 21:52:58 +0000 (13:52 -0800)]
I got all of these backwards.  We want to return

min(input timeout, new timeout)

to userspace to prevent increasing the time-remaining value.

Thanks to Ernst Herzberg <earny@net4u.de> for reporting and diagnosing.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

fs/compat.c
fs/select.c

index a2ba78b..5333c7d 100644 (file)
@@ -1757,7 +1757,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
                        goto sticky;
                rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ));
                rtv.tv_sec = timeout;
-               if (compat_timeval_compare(&rtv, &tv) < 0)
+               if (compat_timeval_compare(&rtv, &tv) >= 0)
                        rtv = tv;
                if (copy_to_user(tvp, &rtv, sizeof(rtv))) {
 sticky:
@@ -1834,7 +1834,7 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
                        rts.tv_sec++;
                        rts.tv_nsec -= NSEC_PER_SEC;
                }
-               if (compat_timespec_compare(&rts, &ts) < 0)
+               if (compat_timespec_compare(&rts, &ts) >= 0)
                        rts = ts;
                copy_to_user(tsp, &rts, sizeof(rts));
        }
@@ -1934,7 +1934,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
                rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) *
                                        1000;
                rts.tv_sec = timeout;
-               if (compat_timespec_compare(&rts, &ts) < 0)
+               if (compat_timespec_compare(&rts, &ts) >= 0)
                        rts = ts;
                if (copy_to_user(tsp, &rts, sizeof(rts))) {
 sticky:
index 6ce68a9..1815a57 100644 (file)
@@ -404,7 +404,7 @@ asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
                        goto sticky;
                rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ));
                rtv.tv_sec = timeout;
-               if (timeval_compare(&rtv, &tv) < 0)
+               if (timeval_compare(&rtv, &tv) >= 0)
                        rtv = tv;
                if (copy_to_user(tvp, &rtv, sizeof(rtv))) {
 sticky:
@@ -471,7 +471,7 @@ asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp,
                rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) *
                                                1000;
                rts.tv_sec = timeout;
-               if (timespec_compare(&rts, &ts) < 0)
+               if (timespec_compare(&rts, &ts) >= 0)
                        rts = ts;
                if (copy_to_user(tsp, &rts, sizeof(rts))) {
 sticky:
@@ -775,7 +775,7 @@ asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds,
                rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) *
                                                1000;
                rts.tv_sec = timeout;
-               if (timespec_compare(&rts, &ts) < 0)
+               if (timespec_compare(&rts, &ts) >= 0)
                        rts = ts;
                if (copy_to_user(tsp, &rts, sizeof(rts))) {
                sticky: