diff options
Diffstat (limited to 'fs/select.c')
-rw-r--r-- | fs/select.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/fs/select.c b/fs/select.c index c0f02d36c60e..1815a57d2255 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -398,11 +398,15 @@ asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp, | |||
398 | ret = core_sys_select(n, inp, outp, exp, &timeout); | 398 | ret = core_sys_select(n, inp, outp, exp, &timeout); |
399 | 399 | ||
400 | if (tvp) { | 400 | if (tvp) { |
401 | struct timeval rtv; | ||
402 | |||
401 | if (current->personality & STICKY_TIMEOUTS) | 403 | if (current->personality & STICKY_TIMEOUTS) |
402 | goto sticky; | 404 | goto sticky; |
403 | tv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)); | 405 | rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)); |
404 | tv.tv_sec = timeout; | 406 | rtv.tv_sec = timeout; |
405 | if (copy_to_user(tvp, &tv, sizeof(tv))) { | 407 | if (timeval_compare(&rtv, &tv) >= 0) |
408 | rtv = tv; | ||
409 | if (copy_to_user(tvp, &rtv, sizeof(rtv))) { | ||
406 | sticky: | 410 | sticky: |
407 | /* | 411 | /* |
408 | * If an application puts its timeval in read-only | 412 | * If an application puts its timeval in read-only |
@@ -460,11 +464,16 @@ asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp, | |||
460 | ret = core_sys_select(n, inp, outp, exp, &timeout); | 464 | ret = core_sys_select(n, inp, outp, exp, &timeout); |
461 | 465 | ||
462 | if (tsp) { | 466 | if (tsp) { |
467 | struct timespec rts; | ||
468 | |||
463 | if (current->personality & STICKY_TIMEOUTS) | 469 | if (current->personality & STICKY_TIMEOUTS) |
464 | goto sticky; | 470 | goto sticky; |
465 | ts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * 1000; | 471 | rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * |
466 | ts.tv_sec = timeout; | 472 | 1000; |
467 | if (copy_to_user(tsp, &ts, sizeof(ts))) { | 473 | rts.tv_sec = timeout; |
474 | if (timespec_compare(&rts, &ts) >= 0) | ||
475 | rts = ts; | ||
476 | if (copy_to_user(tsp, &rts, sizeof(rts))) { | ||
468 | sticky: | 477 | sticky: |
469 | /* | 478 | /* |
470 | * If an application puts its timeval in read-only | 479 | * If an application puts its timeval in read-only |
@@ -510,9 +519,9 @@ asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, | |||
510 | 519 | ||
511 | if (sig) { | 520 | if (sig) { |
512 | if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t)) | 521 | if (!access_ok(VERIFY_READ, sig, sizeof(void *)+sizeof(size_t)) |
513 | || __get_user(up, (sigset_t * __user *)sig) | 522 | || __get_user(up, (sigset_t __user * __user *)sig) |
514 | || __get_user(sigsetsize, | 523 | || __get_user(sigsetsize, |
515 | (size_t * __user)(sig+sizeof(void *)))) | 524 | (size_t __user *)(sig+sizeof(void *)))) |
516 | return -EFAULT; | 525 | return -EFAULT; |
517 | } | 526 | } |
518 | 527 | ||
@@ -758,12 +767,17 @@ asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, | |||
758 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | 767 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); |
759 | 768 | ||
760 | if (tsp && timeout >= 0) { | 769 | if (tsp && timeout >= 0) { |
770 | struct timespec rts; | ||
771 | |||
761 | if (current->personality & STICKY_TIMEOUTS) | 772 | if (current->personality & STICKY_TIMEOUTS) |
762 | goto sticky; | 773 | goto sticky; |
763 | /* Yes, we know it's actually an s64, but it's also positive. */ | 774 | /* Yes, we know it's actually an s64, but it's also positive. */ |
764 | ts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * 1000; | 775 | rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * |
765 | ts.tv_sec = timeout; | 776 | 1000; |
766 | if (copy_to_user(tsp, &ts, sizeof(ts))) { | 777 | rts.tv_sec = timeout; |
778 | if (timespec_compare(&rts, &ts) >= 0) | ||
779 | rts = ts; | ||
780 | if (copy_to_user(tsp, &rts, sizeof(rts))) { | ||
767 | sticky: | 781 | sticky: |
768 | /* | 782 | /* |
769 | * If an application puts its timeval in read-only | 783 | * If an application puts its timeval in read-only |