aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c39
1 files changed, 22 insertions, 17 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 8d0a0018a7d2..a7e3f162fb15 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -45,6 +45,8 @@
45#include <linux/personality.h> 45#include <linux/personality.h>
46#include <linux/rwsem.h> 46#include <linux/rwsem.h>
47#include <linux/tsacct_kern.h> 47#include <linux/tsacct_kern.h>
48#include <linux/highmem.h>
49#include <linux/poll.h>
48#include <linux/mm.h> 50#include <linux/mm.h>
49 51
50#include <net/sock.h> /* siocdevprivate_ioctl */ 52#include <net/sock.h> /* siocdevprivate_ioctl */
@@ -869,7 +871,7 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
869 871
870 retval = -EINVAL; 872 retval = -EINVAL;
871 873
872 if (type_page) { 874 if (type_page && data_page) {
873 if (!strcmp((char *)type_page, SMBFS_NAME)) { 875 if (!strcmp((char *)type_page, SMBFS_NAME)) {
874 do_smb_super_data_conv((void *)data_page); 876 do_smb_super_data_conv((void *)data_page);
875 } else if (!strcmp((char *)type_page, NCPFS_NAME)) { 877 } else if (!strcmp((char *)type_page, NCPFS_NAME)) {
@@ -1142,7 +1144,9 @@ asmlinkage long compat_sys_getdents64(unsigned int fd,
1142 lastdirent = buf.previous; 1144 lastdirent = buf.previous;
1143 if (lastdirent) { 1145 if (lastdirent) {
1144 typeof(lastdirent->d_off) d_off = file->f_pos; 1146 typeof(lastdirent->d_off) d_off = file->f_pos;
1145 __put_user_unaligned(d_off, &lastdirent->d_off); 1147 error = -EFAULT;
1148 if (__put_user_unaligned(d_off, &lastdirent->d_off))
1149 goto out_putf;
1146 error = count - buf.count; 1150 error = count - buf.count;
1147 } 1151 }
1148 1152
@@ -1609,14 +1613,14 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1609 nr &= ~1UL; 1613 nr &= ~1UL;
1610 while (nr) { 1614 while (nr) {
1611 unsigned long h, l; 1615 unsigned long h, l;
1612 __get_user(l, ufdset); 1616 if (__get_user(l, ufdset) || __get_user(h, ufdset+1))
1613 __get_user(h, ufdset+1); 1617 return -EFAULT;
1614 ufdset += 2; 1618 ufdset += 2;
1615 *fdset++ = h << 32 | l; 1619 *fdset++ = h << 32 | l;
1616 nr -= 2; 1620 nr -= 2;
1617 } 1621 }
1618 if (odd) 1622 if (odd && __get_user(*fdset, ufdset))
1619 __get_user(*fdset, ufdset); 1623 return -EFAULT;
1620 } else { 1624 } else {
1621 /* Tricky, must clear full unsigned long in the 1625 /* Tricky, must clear full unsigned long in the
1622 * kernel fdset at the end, this makes sure that 1626 * kernel fdset at the end, this makes sure that
@@ -1628,14 +1632,14 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1628} 1632}
1629 1633
1630static 1634static
1631void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, 1635int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1632 unsigned long *fdset) 1636 unsigned long *fdset)
1633{ 1637{
1634 unsigned long odd; 1638 unsigned long odd;
1635 nr = ROUND_UP(nr, __COMPAT_NFDBITS); 1639 nr = ROUND_UP(nr, __COMPAT_NFDBITS);
1636 1640
1637 if (!ufdset) 1641 if (!ufdset)
1638 return; 1642 return 0;
1639 1643
1640 odd = nr & 1UL; 1644 odd = nr & 1UL;
1641 nr &= ~1UL; 1645 nr &= ~1UL;
@@ -1643,13 +1647,14 @@ void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
1643 unsigned long h, l; 1647 unsigned long h, l;
1644 l = *fdset++; 1648 l = *fdset++;
1645 h = l >> 32; 1649 h = l >> 32;
1646 __put_user(l, ufdset); 1650 if (__put_user(l, ufdset) || __put_user(h, ufdset+1))
1647 __put_user(h, ufdset+1); 1651 return -EFAULT;
1648 ufdset += 2; 1652 ufdset += 2;
1649 nr -= 2; 1653 nr -= 2;
1650 } 1654 }
1651 if (odd) 1655 if (odd && __put_user(*fdset, ufdset))
1652 __put_user(*fdset, ufdset); 1656 return -EFAULT;
1657 return 0;
1653} 1658}
1654 1659
1655 1660
@@ -1724,10 +1729,10 @@ int compat_core_sys_select(int n, compat_ulong_t __user *inp,
1724 ret = 0; 1729 ret = 0;
1725 } 1730 }
1726 1731
1727 compat_set_fd_set(n, inp, fds.res_in); 1732 if (compat_set_fd_set(n, inp, fds.res_in) ||
1728 compat_set_fd_set(n, outp, fds.res_out); 1733 compat_set_fd_set(n, outp, fds.res_out) ||
1729 compat_set_fd_set(n, exp, fds.res_ex); 1734 compat_set_fd_set(n, exp, fds.res_ex))
1730 1735 ret = -EFAULT;
1731out: 1736out:
1732 kfree(bits); 1737 kfree(bits);
1733out_nofds: 1738out_nofds: