aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c55
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
76asmlinkage long compat_sys_futimesat(int dfd, char __user *filename, struct compat_timeval __user *t) 76asmlinkage 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
117asmlinkage long compat_sys_newfstatat(int dfd, char __user *filename, 117asmlinkage 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 */
1328asmlinkage long 1328asmlinkage long
1329compat_sys_openat(int dfd, const char __user *filename, int flags, int mode) 1329compat_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))) {
1759sticky: 1763sticky:
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))) {
1927sticky: 1940sticky:
1928 /* 1941 /*
1929 * If an application puts its timeval in read-only 1942 * If an application puts its timeval in read-only