aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c308
1 files changed, 265 insertions, 43 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 2468ac1df2f0..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,10 +107,31 @@ 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);
111
112 if (!error)
113 error = cp_compat_stat(&stat, statbuf);
114 return error;
115}
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);
104 130
105 if (!error) 131 if (!error)
106 error = cp_compat_stat(&stat, statbuf); 132 error = cp_compat_stat(&stat, statbuf);
133
134out:
107 return error; 135 return error;
108} 136}
109 137
@@ -1290,7 +1318,17 @@ out:
1290asmlinkage long 1318asmlinkage long
1291compat_sys_open(const char __user *filename, int flags, int mode) 1319compat_sys_open(const char __user *filename, int flags, int mode)
1292{ 1320{
1293 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);
1294} 1332}
1295 1333
1296/* 1334/*
@@ -1621,36 +1659,14 @@ static void select_bits_free(void *bits, int size)
1621#define MAX_SELECT_SECONDS \ 1659#define MAX_SELECT_SECONDS \
1622 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1) 1660 ((unsigned long) (MAX_SCHEDULE_TIMEOUT / HZ)-1)
1623 1661
1624asmlinkage long 1662int compat_core_sys_select(int n, compat_ulong_t __user *inp,
1625compat_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)
1626 compat_ulong_t __user *exp, struct compat_timeval __user *tvp)
1627{ 1664{
1628 fd_set_bits fds; 1665 fd_set_bits fds;
1629 char *bits; 1666 char *bits;
1630 long timeout;
1631 int size, max_fdset, ret = -EINVAL; 1667 int size, max_fdset, ret = -EINVAL;
1632 struct fdtable *fdt; 1668 struct fdtable *fdt;
1633 1669
1634 timeout = MAX_SCHEDULE_TIMEOUT;
1635 if (tvp) {
1636 time_t sec, usec;
1637
1638 if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
1639 || __get_user(sec, &tvp->tv_sec)
1640 || __get_user(usec, &tvp->tv_usec)) {
1641 ret = -EFAULT;
1642 goto out_nofds;
1643 }
1644
1645 if (sec < 0 || usec < 0)
1646 goto out_nofds;
1647
1648 if ((unsigned long) sec < MAX_SELECT_SECONDS) {
1649 timeout = ROUND_UP(usec, 1000000/HZ);
1650 timeout += sec * (unsigned long) HZ;
1651 }
1652 }
1653
1654 if (n < 0) 1670 if (n < 0)
1655 goto out_nofds; 1671 goto out_nofds;
1656 1672
@@ -1687,19 +1703,7 @@ compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp
1687 zero_fd_set(n, fds.res_out); 1703 zero_fd_set(n, fds.res_out);
1688 zero_fd_set(n, fds.res_ex); 1704 zero_fd_set(n, fds.res_ex);
1689 1705
1690 ret = do_select(n, &fds, &timeout); 1706 ret = do_select(n, &fds, timeout);
1691
1692 if (tvp && !(current->personality & STICKY_TIMEOUTS)) {
1693 time_t sec = 0, usec = 0;
1694 if (timeout) {
1695 sec = timeout / HZ;
1696 usec = timeout % HZ;
1697 usec *= (1000000/HZ);
1698 }
1699 if (put_user(sec, &tvp->tv_sec) ||
1700 put_user(usec, &tvp->tv_usec))
1701 ret = -EFAULT;
1702 }
1703 1707
1704 if (ret < 0) 1708 if (ret < 0)
1705 goto out; 1709 goto out;
@@ -1720,6 +1724,224 @@ out_nofds:
1720 return ret; 1724 return ret;
1721} 1725}
1722 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
1723#if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE) 1945#if defined(CONFIG_NFSD) || defined(CONFIG_NFSD_MODULE)
1724/* Stuff for NFS server syscalls... */ 1946/* Stuff for NFS server syscalls... */
1725struct compat_nfsctl_svc { 1947struct compat_nfsctl_svc {