aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c136
1 files changed, 20 insertions, 116 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 424767c954a0..133ed7f5d681 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1568,7 +1568,8 @@ int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1568 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) 1568 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1569 1569
1570int compat_core_sys_select(int n, compat_ulong_t __user *inp, 1570int compat_core_sys_select(int n, compat_ulong_t __user *inp,
1571 compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout) 1571 compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1572 struct timespec *end_time)
1572{ 1573{
1573 fd_set_bits fds; 1574 fd_set_bits fds;
1574 void *bits; 1575 void *bits;
@@ -1615,7 +1616,7 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
1615 zero_fd_set(n, fds.res_out); 1616 zero_fd_set(n, fds.res_out);
1616 zero_fd_set(n, fds.res_ex); 1617 zero_fd_set(n, fds.res_ex);
1617 1618
1618 ret = do_select(n, &fds, timeout); 1619 ret = do_select(n, &fds, end_time);
1619 1620
1620 if (ret < 0) 1621 if (ret < 0)
1621 goto out; 1622 goto out;
@@ -1641,7 +1642,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
1641 compat_ulong_t __user *outp, compat_ulong_t __user *exp, 1642 compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1642 struct compat_timeval __user *tvp) 1643 struct compat_timeval __user *tvp)
1643{ 1644{
1644 s64 timeout = -1; 1645 struct timespec end_time, *to = NULL;
1645 struct compat_timeval tv; 1646 struct compat_timeval tv;
1646 int ret; 1647 int ret;
1647 1648
@@ -1649,43 +1650,14 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
1649 if (copy_from_user(&tv, tvp, sizeof(tv))) 1650 if (copy_from_user(&tv, tvp, sizeof(tv)))
1650 return -EFAULT; 1651 return -EFAULT;
1651 1652
1652 if (tv.tv_sec < 0 || tv.tv_usec < 0) 1653 to = &end_time;
1654 if (poll_select_set_timeout(to, tv.tv_sec,
1655 tv.tv_usec * NSEC_PER_USEC))
1653 return -EINVAL; 1656 return -EINVAL;
1654
1655 /* Cast to u64 to make GCC stop complaining */
1656 if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
1657 timeout = -1; /* infinite */
1658 else {
1659 timeout = DIV_ROUND_UP(tv.tv_usec, 1000000/HZ);
1660 timeout += tv.tv_sec * HZ;
1661 }
1662 } 1657 }
1663 1658
1664 ret = compat_core_sys_select(n, inp, outp, exp, &timeout); 1659 ret = compat_core_sys_select(n, inp, outp, exp, to);
1665 1660 ret = poll_select_copy_remaining(&end_time, tvp, 1, ret);
1666 if (tvp) {
1667 struct compat_timeval rtv;
1668
1669 if (current->personality & STICKY_TIMEOUTS)
1670 goto sticky;
1671 rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ));
1672 rtv.tv_sec = timeout;
1673 if (compat_timeval_compare(&rtv, &tv) >= 0)
1674 rtv = tv;
1675 if (copy_to_user(tvp, &rtv, sizeof(rtv))) {
1676sticky:
1677 /*
1678 * If an application puts its timeval in read-only
1679 * memory, we don't want the Linux-specific update to
1680 * the timeval to cause a fault after the select has
1681 * completed successfully. However, because we're not
1682 * updating the timeval, we can't restart the system
1683 * call.
1684 */
1685 if (ret == -ERESTARTNOHAND)
1686 ret = -EINTR;
1687 }
1688 }
1689 1661
1690 return ret; 1662 return ret;
1691} 1663}
@@ -1698,15 +1670,16 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
1698{ 1670{
1699 compat_sigset_t ss32; 1671 compat_sigset_t ss32;
1700 sigset_t ksigmask, sigsaved; 1672 sigset_t ksigmask, sigsaved;
1701 s64 timeout = MAX_SCHEDULE_TIMEOUT;
1702 struct compat_timespec ts; 1673 struct compat_timespec ts;
1674 struct timespec end_time, *to = NULL;
1703 int ret; 1675 int ret;
1704 1676
1705 if (tsp) { 1677 if (tsp) {
1706 if (copy_from_user(&ts, tsp, sizeof(ts))) 1678 if (copy_from_user(&ts, tsp, sizeof(ts)))
1707 return -EFAULT; 1679 return -EFAULT;
1708 1680
1709 if (ts.tv_sec < 0 || ts.tv_nsec < 0) 1681 to = &end_time;
1682 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
1710 return -EINVAL; 1683 return -EINVAL;
1711 } 1684 }
1712 1685
@@ -1721,51 +1694,8 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
1721 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1694 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1722 } 1695 }
1723 1696
1724 do { 1697 ret = compat_core_sys_select(n, inp, outp, exp, to);
1725 if (tsp) { 1698 ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
1726 if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) {
1727 timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
1728 timeout += ts.tv_sec * (unsigned long)HZ;
1729 ts.tv_sec = 0;
1730 ts.tv_nsec = 0;
1731 } else {
1732 ts.tv_sec -= MAX_SELECT_SECONDS;
1733 timeout = MAX_SELECT_SECONDS * HZ;
1734 }
1735 }
1736
1737 ret = compat_core_sys_select(n, inp, outp, exp, &timeout);
1738
1739 } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec));
1740
1741 if (tsp) {
1742 struct compat_timespec rts;
1743
1744 if (current->personality & STICKY_TIMEOUTS)
1745 goto sticky;
1746
1747 rts.tv_sec = timeout / HZ;
1748 rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ);
1749 if (rts.tv_nsec >= NSEC_PER_SEC) {
1750 rts.tv_sec++;
1751 rts.tv_nsec -= NSEC_PER_SEC;
1752 }
1753 if (compat_timespec_compare(&rts, &ts) >= 0)
1754 rts = ts;
1755 if (copy_to_user(tsp, &rts, sizeof(rts))) {
1756sticky:
1757 /*
1758 * If an application puts its timeval in read-only
1759 * memory, we don't want the Linux-specific update to
1760 * the timeval to cause a fault after the select has
1761 * completed successfully. However, because we're not
1762 * updating the timeval, we can't restart the system
1763 * call.
1764 */
1765 if (ret == -ERESTARTNOHAND)
1766 ret = -EINTR;
1767 }
1768 }
1769 1699
1770 if (ret == -ERESTARTNOHAND) { 1700 if (ret == -ERESTARTNOHAND) {
1771 /* 1701 /*
@@ -1810,18 +1740,16 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
1810 compat_sigset_t ss32; 1740 compat_sigset_t ss32;
1811 sigset_t ksigmask, sigsaved; 1741 sigset_t ksigmask, sigsaved;
1812 struct compat_timespec ts; 1742 struct compat_timespec ts;
1813 s64 timeout = -1; 1743 struct timespec end_time, *to = NULL;
1814 int ret; 1744 int ret;
1815 1745
1816 if (tsp) { 1746 if (tsp) {
1817 if (copy_from_user(&ts, tsp, sizeof(ts))) 1747 if (copy_from_user(&ts, tsp, sizeof(ts)))
1818 return -EFAULT; 1748 return -EFAULT;
1819 1749
1820 /* We assume that ts.tv_sec is always lower than 1750 to = &end_time;
1821 the number of seconds that can be expressed in 1751 if (poll_select_set_timeout(to, ts.tv_sec, ts.tv_nsec))
1822 an s64. Otherwise the compiler bitches at us */ 1752 return -EINVAL;
1823 timeout = DIV_ROUND_UP(ts.tv_nsec, 1000000000/HZ);
1824 timeout += ts.tv_sec * HZ;
1825 } 1753 }
1826 1754
1827 if (sigmask) { 1755 if (sigmask) {
@@ -1835,7 +1763,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
1835 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); 1763 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1836 } 1764 }
1837 1765
1838 ret = do_sys_poll(ufds, nfds, &timeout); 1766 ret = do_sys_poll(ufds, nfds, to);
1839 1767
1840 /* We can restart this syscall, usually */ 1768 /* We can restart this syscall, usually */
1841 if (ret == -EINTR) { 1769 if (ret == -EINTR) {
@@ -1853,31 +1781,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
1853 } else if (sigmask) 1781 } else if (sigmask)
1854 sigprocmask(SIG_SETMASK, &sigsaved, NULL); 1782 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1855 1783
1856 if (tsp && timeout >= 0) { 1784 ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
1857 struct compat_timespec rts;
1858
1859 if (current->personality & STICKY_TIMEOUTS)
1860 goto sticky;
1861 /* Yes, we know it's actually an s64, but it's also positive. */
1862 rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) *
1863 1000;
1864 rts.tv_sec = timeout;
1865 if (compat_timespec_compare(&rts, &ts) >= 0)
1866 rts = ts;
1867 if (copy_to_user(tsp, &rts, sizeof(rts))) {
1868sticky:
1869 /*
1870 * If an application puts its timeval in read-only
1871 * memory, we don't want the Linux-specific update to
1872 * the timeval to cause a fault after the select has
1873 * completed successfully. However, because we're not
1874 * updating the timeval, we can't restart the system
1875 * call.
1876 */
1877 if (ret == -ERESTARTNOHAND && timeout >= 0)
1878 ret = -EINTR;
1879 }
1880 }
1881 1785
1882 return ret; 1786 return ret;
1883} 1787}