aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c359
1 files changed, 294 insertions, 65 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 8e71cdbecc7c..ff0bafcff720 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -53,6 +53,8 @@
53#include <asm/mmu_context.h> 53#include <asm/mmu_context.h>
54#include <asm/ioctls.h> 54#include <asm/ioctls.h>
55 55
56extern void sigset_from_compat(sigset_t *set, compat_sigset_t *compat);
57
56/* 58/*
57 * Not all architectures have sys_utime, so implement this in terms 59 * Not all architectures have sys_utime, so implement this in terms
58 * of sys_utimes. 60 * of sys_utimes.
@@ -68,10 +70,10 @@ asmlinkage long compat_sys_utime(char __user *filename, struct compat_utimbuf __
68 tv[0].tv_usec = 0; 70 tv[0].tv_usec = 0;
69 tv[1].tv_usec = 0; 71 tv[1].tv_usec = 0;
70 } 72 }
71 return do_utimes(filename, t ? tv : NULL); 73 return do_utimes(AT_FDCWD, filename, t ? tv : NULL);
72} 74}
73 75
74asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t) 76asmlinkage long compat_sys_futimesat(int dfd, char __user *filename, struct compat_timeval __user *t)
75{ 77{
76 struct timeval tv[2]; 78 struct timeval tv[2];
77 79
@@ -82,14 +84,19 @@ asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval _
82 get_user(tv[1].tv_usec, &t[1].tv_usec)) 84 get_user(tv[1].tv_usec, &t[1].tv_usec))
83 return -EFAULT; 85 return -EFAULT;
84 } 86 }
85 return do_utimes(filename, t ? tv : NULL); 87 return do_utimes(dfd, filename, t ? tv : NULL);
88}
89
90asmlinkage long compat_sys_utimes(char __user *filename, struct compat_timeval __user *t)
91{
92 return compat_sys_futimesat(AT_FDCWD, filename, t);
86} 93}
87 94
88asmlinkage long compat_sys_newstat(char __user * filename, 95asmlinkage long compat_sys_newstat(char __user * filename,
89 struct compat_stat __user *statbuf) 96 struct compat_stat __user *statbuf)
90{ 97{
91 struct kstat stat; 98 struct kstat stat;
92 int error = vfs_stat(filename, &stat); 99 int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
93 100
94 if (!error) 101 if (!error)
95 error = cp_compat_stat(&stat, statbuf); 102 error = cp_compat_stat(&stat, statbuf);
@@ -100,13 +107,34 @@ asmlinkage long compat_sys_newlstat(char __user * filename,
100 struct compat_stat __user *statbuf) 107 struct compat_stat __user *statbuf)
101{ 108{
102 struct kstat stat; 109 struct kstat stat;
103 int error = vfs_lstat(filename, &stat); 110 int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
104 111
105 if (!error) 112 if (!error)
106 error = cp_compat_stat(&stat, statbuf); 113 error = cp_compat_stat(&stat, statbuf);
107 return error; 114 return error;
108} 115}
109 116
117asmlinkage long compat_sys_newfstatat(int dfd, char __user *filename,
118 struct compat_stat __user *statbuf, int flag)
119{
120 struct kstat stat;
121 int error = -EINVAL;
122
123 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
124 goto out;
125
126 if (flag & AT_SYMLINK_NOFOLLOW)
127 error = vfs_lstat_fd(dfd, filename, &stat);
128 else
129 error = vfs_stat_fd(dfd, filename, &stat);
130
131 if (!error)
132 error = cp_compat_stat(&stat, statbuf);
133
134out:
135 return error;
136}
137
110asmlinkage long compat_sys_newfstat(unsigned int fd, 138asmlinkage long compat_sys_newfstat(unsigned int fd,
111 struct compat_stat __user * statbuf) 139 struct compat_stat __user * statbuf)
112{ 140{
@@ -168,8 +196,8 @@ asmlinkage long compat_sys_statfs(const char __user *path, struct compat_statfs
168 if (!error) { 196 if (!error) {
169 struct kstatfs tmp; 197 struct kstatfs tmp;
170 error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); 198 error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
171 if (!error && put_compat_statfs(buf, &tmp)) 199 if (!error)
172 error = -EFAULT; 200 error = put_compat_statfs(buf, &tmp);
173 path_release(&nd); 201 path_release(&nd);
174 } 202 }
175 return error; 203 return error;
@@ -186,8 +214,8 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user
186 if (!file) 214 if (!file)
187 goto out; 215 goto out;
188 error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); 216 error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
189 if (!error && put_compat_statfs(buf, &tmp)) 217 if (!error)
190 error = -EFAULT; 218 error = put_compat_statfs(buf, &tmp);
191 fput(file); 219 fput(file);
192out: 220out:
193 return error; 221 return error;
@@ -236,8 +264,8 @@ asmlinkage long compat_sys_statfs64(const char __user *path, compat_size_t sz, s
236 if (!error) { 264 if (!error) {
237 struct kstatfs tmp; 265 struct kstatfs tmp;
238 error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp); 266 error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
239 if (!error && put_compat_statfs64(buf, &tmp)) 267 if (!error)
240 error = -EFAULT; 268 error = put_compat_statfs64(buf, &tmp);
241 path_release(&nd); 269 path_release(&nd);
242 } 270 }
243 return error; 271 return error;
@@ -257,8 +285,8 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c
257 if (!file) 285 if (!file)
258 goto out; 286 goto out;
259 error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp); 287 error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
260 if (!error && put_compat_statfs64(buf, &tmp)) 288 if (!error)
261 error = -EFAULT; 289 error = put_compat_statfs64(buf, &tmp);
262 fput(file); 290 fput(file);
263out: 291out:
264 return error; 292 return error;
@@ -268,7 +296,6 @@ out:
268 296
269#define IOCTL_HASHSIZE 256 297#define IOCTL_HASHSIZE 256
270static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE]; 298static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
271static DECLARE_RWSEM(ioctl32_sem);
272 299
273extern struct ioctl_trans ioctl_start[]; 300extern struct ioctl_trans ioctl_start[];
274extern int ioctl_table_size; 301extern int ioctl_table_size;
@@ -390,14 +417,10 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
390 break; 417 break;
391 } 418 }
392 419
393 /* When register_ioctl32_conversion is finally gone remove
394 this lock! -AK */
395 down_read(&ioctl32_sem);
396 for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) { 420 for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) {
397 if (t->cmd == cmd) 421 if (t->cmd == cmd)
398 goto found_handler; 422 goto found_handler;
399 } 423 }
400 up_read(&ioctl32_sem);
401 424
402 if (S_ISSOCK(filp->f_dentry->d_inode->i_mode) && 425 if (S_ISSOCK(filp->f_dentry->d_inode->i_mode) &&
403 cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { 426 cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
@@ -417,11 +440,9 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
417 lock_kernel(); 440 lock_kernel();
418 error = t->handler(fd, cmd, arg, filp); 441 error = t->handler(fd, cmd, arg, filp);
419 unlock_kernel(); 442 unlock_kernel();
420 up_read(&ioctl32_sem);
421 goto out_fput; 443 goto out_fput;
422 } 444 }
423 445
424 up_read(&ioctl32_sem);
425 do_ioctl: 446 do_ioctl:
426 error = vfs_ioctl(filp, fd, cmd, arg); 447 error = vfs_ioctl(filp, fd, cmd, arg);
427 out_fput: 448 out_fput:
@@ -501,9 +522,21 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
501 ret = sys_fcntl(fd, cmd, (unsigned long)&f); 522 ret = sys_fcntl(fd, cmd, (unsigned long)&f);
502 set_fs(old_fs); 523 set_fs(old_fs);
503 if (cmd == F_GETLK && ret == 0) { 524 if (cmd == F_GETLK && ret == 0) {
504 if ((f.l_start >= COMPAT_OFF_T_MAX) || 525 /* GETLK was successfule and we need to return the data...
505 ((f.l_start + f.l_len) > COMPAT_OFF_T_MAX)) 526 * but it needs to fit in the compat structure.
527 * l_start shouldn't be too big, unless the original
528 * start + end is greater than COMPAT_OFF_T_MAX, in which
529 * case the app was asking for trouble, so we return
530 * -EOVERFLOW in that case.
531 * l_len could be too big, in which case we just truncate it,
532 * and only allow the app to see that part of the conflicting
533 * lock that might make sense to it anyway
534 */
535
536 if (f.l_start > COMPAT_OFF_T_MAX)
506 ret = -EOVERFLOW; 537 ret = -EOVERFLOW;
538 if (f.l_len > COMPAT_OFF_T_MAX)
539 f.l_len = COMPAT_OFF_T_MAX;
507 if (ret == 0) 540 if (ret == 0)
508 ret = put_compat_flock(&f, compat_ptr(arg)); 541 ret = put_compat_flock(&f, compat_ptr(arg));
509 } 542 }
@@ -522,9 +555,11 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
522 (unsigned long)&f); 555 (unsigned long)&f);
523 set_fs(old_fs); 556 set_fs(old_fs);
524 if (cmd == F_GETLK64 && ret == 0) { 557 if (cmd == F_GETLK64 && ret == 0) {
525 if ((f.l_start >= COMPAT_LOFF_T_MAX) || 558 /* need to return lock information - see above for commentary */
526 ((f.l_start + f.l_len) > COMPAT_LOFF_T_MAX)) 559 if (f.l_start > COMPAT_LOFF_T_MAX)
527 ret = -EOVERFLOW; 560 ret = -EOVERFLOW;
561 if (f.l_len > COMPAT_LOFF_T_MAX)
562 f.l_len = COMPAT_LOFF_T_MAX;
528 if (ret == 0) 563 if (ret == 0)
529 ret = put_compat_flock64(&f, compat_ptr(arg)); 564 ret = put_compat_flock64(&f, compat_ptr(arg));
530 } 565 }
@@ -1177,7 +1212,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
1177 } 1212 }
1178 1213
1179 ret = rw_verify_area(type, file, pos, tot_len); 1214 ret = rw_verify_area(type, file, pos, tot_len);
1180 if (ret) 1215 if (ret < 0)
1181 goto out; 1216 goto out;
1182 1217
1183 fnv = NULL; 1218 fnv = NULL;
@@ -1283,7 +1318,17 @@ out:
1283asmlinkage long 1318asmlinkage long
1284compat_sys_open(const char __user *filename, int flags, int mode) 1319compat_sys_open(const char __user *filename, int flags, int mode)
1285{ 1320{
1286 return do_sys_open(filename, flags, mode); 1321 return do_sys_open(AT_FDCWD, filename, flags, mode);
1322}
1323
1324/*
1325 * Exactly like fs/open.c:sys_openat(), except that it doesn't set the
1326 * O_LARGEFILE flag.
1327 */
1328asmlinkage long
1329compat_sys_openat(int dfd, const char __user *filename, int flags, int mode)
1330{
1331 return do_sys_open(dfd, filename, flags, mode);
1287} 1332}
1288 1333
1289/* 1334/*
@@ -1530,7 +1575,7 @@ out_ret:
1530 * Ooo, nasty. We need here to frob 32-bit unsigned longs to 1575 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
1531 * 64-bit unsigned longs. 1576 * 64-bit unsigned longs.
1532 */ 1577 */
1533static inline 1578static
1534int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 1579int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1535 unsigned long *fdset) 1580 unsigned long *fdset)
1536{ 1581{
@@ -1563,7 +1608,7 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1563 return 0; 1608 return 0;
1564} 1609}
1565 1610
1566static inline 1611static
1567void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 1612void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1568 unsigned long *fdset) 1613 unsigned long *fdset)
1569{ 1614{
@@ -1614,36 +1659,14 @@ static void select_bits_free(void *bits, int size)
1614#define MAX_SELECT_SECONDS \ 1659#define MAX_SELECT_SECONDS \
1615 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) 1660 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1616 1661
1617asmlinkage long 1662int compat_core_sys_select(int n, compat_ulong_t __user *inp,
1618compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp, 1663 compat_ulong_t __user *outp, compat_ulong_t __user *exp, s64 *timeout)
1619 compat_ulong_t __user *exp, struct compat_timeval __user *tvp)
1620{ 1664{
1621 fd_set_bits fds; 1665 fd_set_bits fds;
1622 char *bits; 1666 char *bits;
1623 long timeout;
1624 int size, max_fdset, ret = -EINVAL; 1667 int size, max_fdset, ret = -EINVAL;
1625 struct fdtable *fdt; 1668 struct fdtable *fdt;
1626 1669
1627 timeout = MAX_SCHEDULE_TIMEOUT;
1628 if (tvp) {
1629 time_t sec, usec;
1630
1631 if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
1632 || __get_user(sec, &tvp->tv_sec)
1633 || __get_user(usec, &tvp->tv_usec)) {
1634 ret = -EFAULT;
1635 goto out_nofds;
1636 }
1637
1638 if (sec < 0 || usec < 0)
1639 goto out_nofds;
1640
1641 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1642 timeout = ROUND_UP(usec, 1000000/HZ);
1643 timeout += sec * (unsigned long) HZ;
1644 }
1645 }
1646
1647 if (n < 0) 1670 if (n < 0)
1648 goto out_nofds; 1671 goto out_nofds;
1649 1672
@@ -1680,19 +1703,7 @@ compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp
1680 zero_fd_set(n, fds.res_out); 1703 zero_fd_set(n, fds.res_out);
1681 zero_fd_set(n, fds.res_ex); 1704 zero_fd_set(n, fds.res_ex);
1682 1705
1683 ret = do_select(n, &fds, &timeout); 1706 ret = do_select(n, &fds, timeout);
1684
1685 if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1686 time_t sec = 0, usec = 0;
1687 if (timeout) {
1688 sec = timeout / HZ;
1689 usec = timeout % HZ;
1690 usec *= (1000000/HZ);
1691 }
1692 if (put_user(sec, &tvp->tv_sec) ||
1693 put_user(usec, &tvp->tv_usec))
1694 ret = -EFAULT;
1695 }
1696 1707
1697 if (ret < 0) 1708 if (ret < 0)
1698 goto out; 1709 goto out;
@@ -1713,6 +1724,224 @@ out_nofds:
1713 return ret; 1724 return ret;
1714} 1725}
1715 1726
1727asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
1728 compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1729 struct compat_timeval __user *tvp)
1730{
1731 s64 timeout = -1;
1732 struct compat_timeval tv;
1733 int ret;
1734
1735 if (tvp) {
1736 if (copy_from_user(&tv, tvp, sizeof(tv)))
1737 return -EFAULT;
1738
1739 if (tv.tv_sec < 0 || tv.tv_usec < 0)
1740 return -EINVAL;
1741
1742 /* Cast to u64 to make GCC stop complaining */
1743 if ((u64)tv.tv_sec >= (u64)MAX_INT64_SECONDS)
1744 timeout = -1; /* infinite */
1745 else {
1746 timeout = ROUND_UP(tv.tv_usec, 1000000/HZ);
1747 timeout += tv.tv_sec * HZ;
1748 }
1749 }
1750
1751 ret = compat_core_sys_select(n, inp, outp, exp, &timeout);
1752
1753 if (tvp) {
1754 if (current->personality & STICKY_TIMEOUTS)
1755 goto sticky;
1756 tv.tv_usec = jiffies_to_usecs(do_div((*(u64*)&timeout), HZ));
1757 tv.tv_sec = timeout;
1758 if (copy_to_user(tvp, &tv, sizeof(tv))) {
1759sticky:
1760 /*
1761 * If an application puts its timeval in read-only
1762 * memory, we don't want the Linux-specific update to
1763 * the timeval to cause a fault after the select has
1764 * completed successfully. However, because we're not
1765 * updating the timeval, we can't restart the system
1766 * call.
1767 */
1768 if (ret == -ERESTARTNOHAND)
1769 ret = -EINTR;
1770 }
1771 }
1772
1773 return ret;
1774}
1775
1776#ifdef TIF_RESTORE_SIGMASK
1777asmlinkage long compat_sys_pselect7(int n, compat_ulong_t __user *inp,
1778 compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1779 struct compat_timespec __user *tsp, compat_sigset_t __user *sigmask,
1780 compat_size_t sigsetsize)
1781{
1782 compat_sigset_t ss32;
1783 sigset_t ksigmask, sigsaved;
1784 long timeout = MAX_SCHEDULE_TIMEOUT;
1785 struct compat_timespec ts;
1786 int ret;
1787
1788 if (tsp) {
1789 if (copy_from_user(&ts, tsp, sizeof(ts)))
1790 return -EFAULT;
1791
1792 if (ts.tv_sec < 0 || ts.tv_nsec < 0)
1793 return -EINVAL;
1794 }
1795
1796 if (sigmask) {
1797 if (sigsetsize != sizeof(compat_sigset_t))
1798 return -EINVAL;
1799 if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
1800 return -EFAULT;
1801 sigset_from_compat(&ksigmask, &ss32);
1802
1803 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1804 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1805 }
1806
1807 do {
1808 if (tsp) {
1809 if ((unsigned long)ts.tv_sec < MAX_SELECT_SECONDS) {
1810 timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
1811 timeout += ts.tv_sec * (unsigned long)HZ;
1812 ts.tv_sec = 0;
1813 ts.tv_nsec = 0;
1814 } else {
1815 ts.tv_sec -= MAX_SELECT_SECONDS;
1816 timeout = MAX_SELECT_SECONDS * HZ;
1817 }
1818 }
1819
1820 ret = compat_core_sys_select(n, inp, outp, exp, &timeout);
1821
1822 } while (!ret && !timeout && tsp && (ts.tv_sec || ts.tv_nsec));
1823
1824 if (tsp && !(current->personality & STICKY_TIMEOUTS)) {
1825 ts.tv_sec += timeout / HZ;
1826 ts.tv_nsec += (timeout % HZ) * (1000000000/HZ);
1827 if (ts.tv_nsec >= 1000000000) {
1828 ts.tv_sec++;
1829 ts.tv_nsec -= 1000000000;
1830 }
1831 (void)copy_to_user(tsp, &ts, sizeof(ts));
1832 }
1833
1834 if (ret == -ERESTARTNOHAND) {
1835 /*
1836 * Don't restore the signal mask yet. Let do_signal() deliver
1837 * the signal on the way back to userspace, before the signal
1838 * mask is restored.
1839 */
1840 if (sigmask) {
1841 memcpy(&current->saved_sigmask, &sigsaved,
1842 sizeof(sigsaved));
1843 set_thread_flag(TIF_RESTORE_SIGMASK);
1844 }
1845 } else if (sigmask)
1846 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1847
1848 return ret;
1849}
1850
1851asmlinkage long compat_sys_pselect6(int n, compat_ulong_t __user *inp,
1852 compat_ulong_t __user *outp, compat_ulong_t __user *exp,
1853 struct compat_timespec __user *tsp, void __user *sig)
1854{
1855 compat_size_t sigsetsize = 0;
1856 compat_uptr_t up = 0;
1857
1858 if (sig) {
1859 if (!access_ok(VERIFY_READ, sig,
1860 sizeof(compat_uptr_t)+sizeof(compat_size_t)) ||
1861 __get_user(up, (compat_uptr_t __user *)sig) ||
1862 __get_user(sigsetsize,
1863 (compat_size_t __user *)(sig+sizeof(up))))
1864 return -EFAULT;
1865 }
1866 return compat_sys_pselect7(n, inp, outp, exp, tsp, compat_ptr(up),
1867 sigsetsize);
1868}
1869
1870asmlinkage long compat_sys_ppoll(struct pollfd __user *ufds,
1871 unsigned int nfds, struct compat_timespec __user *tsp,
1872 const compat_sigset_t __user *sigmask, compat_size_t sigsetsize)
1873{
1874 compat_sigset_t ss32;
1875 sigset_t ksigmask, sigsaved;
1876 struct compat_timespec ts;
1877 s64 timeout = -1;
1878 int ret;
1879
1880 if (tsp) {
1881 if (copy_from_user(&ts, tsp, sizeof(ts)))
1882 return -EFAULT;
1883
1884 /* We assume that ts.tv_sec is always lower than
1885 the number of seconds that can be expressed in
1886 an s64. Otherwise the compiler bitches at us */
1887 timeout = ROUND_UP(ts.tv_nsec, 1000000000/HZ);
1888 timeout += ts.tv_sec * HZ;
1889 }
1890
1891 if (sigmask) {
1892 if (sigsetsize |= sizeof(compat_sigset_t))
1893 return -EINVAL;
1894 if (copy_from_user(&ss32, sigmask, sizeof(ss32)))
1895 return -EFAULT;
1896 sigset_from_compat(&ksigmask, &ss32);
1897
1898 sigdelsetmask(&ksigmask, sigmask(SIGKILL)|sigmask(SIGSTOP));
1899 sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
1900 }
1901
1902 ret = do_sys_poll(ufds, nfds, &timeout);
1903
1904 /* We can restart this syscall, usually */
1905 if (ret == -EINTR) {
1906 /*
1907 * Don't restore the signal mask yet. Let do_signal() deliver
1908 * the signal on the way back to userspace, before the signal
1909 * mask is restored.
1910 */
1911 if (sigmask) {
1912 memcpy(&current->saved_sigmask, &sigsaved,
1913 sizeof(sigsaved));
1914 set_thread_flag(TIF_RESTORE_SIGMASK);
1915 }
1916 ret = -ERESTARTNOHAND;
1917 } else if (sigmask)
1918 sigprocmask(SIG_SETMASK, &sigsaved, NULL);
1919
1920 if (tsp && timeout >= 0) {
1921 if (current->personality & STICKY_TIMEOUTS)
1922 goto sticky;
1923 /* 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;
1925 ts.tv_sec = timeout;
1926 if (copy_to_user(tsp, &ts, sizeof(ts))) {
1927sticky:
1928 /*
1929 * If an application puts its timeval in read-only
1930 * memory, we don't want the Linux-specific update to
1931 * the timeval to cause a fault after the select has
1932 * completed successfully. However, because we're not
1933 * updating the timeval, we can't restart the system
1934 * call.
1935 */
1936 if (ret == -ERESTARTNOHAND && timeout >= 0)
1937 ret = -EINTR;
1938 }
1939 }
1940
1941 return ret;
1942}
1943#endif /* TIF_RESTORE_SIGMASK */
1944
1716#if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE) 1945#if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)
1717/* Stuff for NFS server syscalls... */ 1946/* Stuff for NFS server syscalls... */
1718struct compat_nfsctl_svc { 1947struct compat_nfsctl_svc {