diff options
Diffstat (limited to 'fs/compat.c')
| -rw-r--r-- | fs/compat.c | 55 | 
1 files changed, 34 insertions, 21 deletions
diff --git a/fs/compat.c b/fs/compat.c index 18b21b4c9e3a..5333c7d7427f 100644 --- a/fs/compat.c +++ b/fs/compat.c  | |||
| @@ -73,17 +73,17 @@ asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __ | |||
| 73 | return do_utimes(AT_FDCWD, filename, t ? tv : NULL); | 73 | return do_utimes(AT_FDCWD, filename, t ? tv : NULL); | 
| 74 | } | 74 | } | 
| 75 | 75 | ||
| 76 | asmlinkage long compat_sys_futimesat(int dfd, char __user *filename, struct compat_timeval __user *t) | 76 | asmlinkage long compat_sys_futimesat(unsigned int dfd, char __user *filename, struct compat_timeval __user *t) | 
| 77 | { | 77 | { | 
| 78 | struct timeval tv[2]; | 78 | struct timeval tv[2]; | 
| 79 | 79 | ||
| 80 | if (t) { | 80 | if (t) { | 
| 81 | if (get_user(tv[0].tv_sec, &t[0].tv_sec) || | 81 | if (get_user(tv[0].tv_sec, &t[0].tv_sec) || | 
| 82 | get_user(tv[0].tv_usec, &t[0].tv_usec) || | 82 | get_user(tv[0].tv_usec, &t[0].tv_usec) || | 
| 83 | get_user(tv[1].tv_sec, &t[1].tv_sec) || | 83 | get_user(tv[1].tv_sec, &t[1].tv_sec) || | 
| 84 | get_user(tv[1].tv_usec, &t[1].tv_usec)) | 84 | get_user(tv[1].tv_usec, &t[1].tv_usec)) | 
| 85 | return -EFAULT; | 85 | return -EFAULT; | 
| 86 | } | 86 | } | 
| 87 | return do_utimes(dfd, filename, t ? tv : NULL); | 87 | return do_utimes(dfd, filename, t ? tv : NULL); | 
| 88 | } | 88 | } | 
| 89 | 89 | ||
| @@ -114,7 +114,7 @@ asmlinkage long compat_sys_newlstat(char __user * filename, | |||
| 114 | return error; | 114 | return error; | 
| 115 | } | 115 | } | 
| 116 | 116 | ||
| 117 | asmlinkage long compat_sys_newfstatat(int dfd, char __user *filename, | 117 | asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename, | 
| 118 | struct compat_stat __user *statbuf, int flag) | 118 | struct compat_stat __user *statbuf, int flag) | 
| 119 | { | 119 | { | 
| 120 | struct kstat stat; | 120 | struct kstat stat; | 
| @@ -1326,7 +1326,7 @@ compat_sys_open(const char __user *filename, int flags, int mode) | |||
| 1326 | * O_LARGEFILE flag. | 1326 | * O_LARGEFILE flag. | 
| 1327 | */ | 1327 | */ | 
| 1328 | asmlinkage long | 1328 | asmlinkage long | 
| 1329 | compat_sys_openat(int dfd, const char __user *filename, int flags, int mode) | 1329 | compat_sys_openat(unsigned int dfd, const char __user *filename, int flags, int mode) | 
| 1330 | { | 1330 | { | 
| 1331 | return do_sys_open(dfd, filename, flags, mode); | 1331 | return do_sys_open(dfd, filename, flags, mode); | 
| 1332 | } | 1332 | } | 
| @@ -1743,7 +1743,7 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, | |||
| 1743 | if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS) | 1743 | if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS) | 
| 1744 | timeout = -1; /* infinite */ | 1744 | timeout = -1; /* infinite */ | 
| 1745 | else { | 1745 | else { | 
| 1746 | timeout = ROUND_UP(tv.tv_sec, 1000000/HZ); | 1746 | timeout = ROUND_UP(tv.tv_usec, 1000000/HZ); | 
| 1747 | timeout += tv.tv_sec * HZ; | 1747 | timeout += tv.tv_sec * HZ; | 
| 1748 | } | 1748 | } | 
| 1749 | } | 1749 | } | 
| @@ -1751,11 +1751,15 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp, | |||
| 1751 | ret = compat_core_sys_select(n, inp, outp, exp, &timeout); | 1751 | ret = compat_core_sys_select(n, inp, outp, exp, &timeout); | 
| 1752 | 1752 | ||
| 1753 | if (tvp) { | 1753 | if (tvp) { | 
| 1754 | struct compat_timeval rtv; | ||
| 1755 | |||
| 1754 | if (current->personality & STICKY_TIMEOUTS) | 1756 | if (current->personality & STICKY_TIMEOUTS) | 
| 1755 | goto sticky; | 1757 | goto sticky; | 
| 1756 | tv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)); | 1758 | rtv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)); | 
| 1757 | tv.tv_sec = timeout; | 1759 | rtv.tv_sec = timeout; | 
| 1758 | if (copy_to_user(tvp, &tv, sizeof(tv))) { | 1760 | if (compat_timeval_compare(&rtv, &tv) >= 0) | 
| 1761 | rtv = tv; | ||
| 1762 | if (copy_to_user(tvp, &rtv, sizeof(rtv))) { | ||
| 1759 | sticky: | 1763 | sticky: | 
| 1760 | /* | 1764 | /* | 
| 1761 | * If an application puts its timeval in read-only | 1765 | * If an application puts its timeval in read-only | 
| @@ -1781,7 +1785,7 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, | |||
| 1781 | { | 1785 | { | 
| 1782 | compat_sigset_t ss32; | 1786 | compat_sigset_t ss32; | 
| 1783 | sigset_t ksigmask, sigsaved; | 1787 | sigset_t ksigmask, sigsaved; | 
| 1784 | long timeout = MAX_SCHEDULE_TIMEOUT; | 1788 | s64 timeout = MAX_SCHEDULE_TIMEOUT; | 
| 1785 | struct compat_timespec ts; | 1789 | struct compat_timespec ts; | 
| 1786 | int ret; | 1790 | int ret; | 
| 1787 | 1791 | ||
| @@ -1822,13 +1826,17 @@ asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp, | |||
| 1822 | } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec)); | 1826 | } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec)); | 
| 1823 | 1827 | ||
| 1824 | if (tsp && !(current->personality & STICKY_TIMEOUTS)) { | 1828 | if (tsp && !(current->personality & STICKY_TIMEOUTS)) { | 
| 1825 | ts.tv_sec += timeout / HZ; | 1829 | struct compat_timespec rts; | 
| 1826 | ts.tv_nsec += (timeout % HZ) * (1000000000/HZ); | 1830 | |
| 1827 | if (ts.tv_nsec >= 1000000000) { | 1831 | rts.tv_sec = timeout / HZ; | 
| 1828 | ts.tv_sec++; | 1832 | rts.tv_nsec = (timeout % HZ) * (NSEC_PER_SEC/HZ); | 
| 1829 | ts.tv_nsec -= 1000000000; | 1833 | if (rts.tv_nsec >= NSEC_PER_SEC) { | 
| 1834 | rts.tv_sec++; | ||
| 1835 | rts.tv_nsec -= NSEC_PER_SEC; | ||
| 1830 | } | 1836 | } | 
| 1831 | (void)copy_to_user(tsp, &ts, sizeof(ts)); | 1837 | if (compat_timespec_compare(&rts, &ts) >= 0) | 
| 1838 | rts = ts; | ||
| 1839 | copy_to_user(tsp, &rts, sizeof(rts)); | ||
| 1832 | } | 1840 | } | 
| 1833 | 1841 | ||
| 1834 | if (ret == -ERESTARTNOHAND) { | 1842 | if (ret == -ERESTARTNOHAND) { | 
| @@ -1884,7 +1892,7 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, | |||
| 1884 | /* We assume that ts.tv_sec is always lower than | 1892 | /* We assume that ts.tv_sec is always lower than | 
| 1885 | the number of seconds that can be expressed in | 1893 | the number of seconds that can be expressed in | 
| 1886 | an s64. Otherwise the compiler bitches at us */ | 1894 | an s64. Otherwise the compiler bitches at us */ | 
| 1887 | timeout = ROUND_UP(ts.tv_sec, 1000000000/HZ); | 1895 | timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ); | 
| 1888 | timeout += ts.tv_sec * HZ; | 1896 | timeout += ts.tv_sec * HZ; | 
| 1889 | } | 1897 | } | 
| 1890 | 1898 | ||
| @@ -1918,12 +1926,17 @@ asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds, | |||
| 1918 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | 1926 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | 
| 1919 | 1927 | ||
| 1920 | if (tsp && timeout >= 0) { | 1928 | if (tsp && timeout >= 0) { | 
| 1929 | struct compat_timespec rts; | ||
| 1930 | |||
| 1921 | if (current->personality & STICKY_TIMEOUTS) | 1931 | if (current->personality & STICKY_TIMEOUTS) | 
| 1922 | goto sticky; | 1932 | goto sticky; | 
| 1923 | /* Yes, we know it's actually an s64, but it's also positive. */ | 1933 | /* Yes, we know it's actually an s64, but it's also positive. */ | 
| 1924 | ts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * 1000; | 1934 | rts.tv_nsec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ)) * | 
| 1925 | ts.tv_sec = timeout; | 1935 | 1000; | 
| 1926 | if (copy_to_user(tsp, &ts, sizeof(ts))) { | 1936 | rts.tv_sec = timeout; | 
| 1937 | if (compat_timespec_compare(&rts, &ts) >= 0) | ||
| 1938 | rts = ts; | ||
| 1939 | if (copy_to_user(tsp, &rts, sizeof(rts))) { | ||
| 1927 | sticky: | 1940 | sticky: | 
| 1928 | /* | 1941 | /* | 
| 1929 | * If an application puts its timeval in read-only | 1942 | * If an application puts its timeval in read-only | 
