diff options
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 39 |
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 | ||
1630 | static | 1634 | static |
1631 | void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset, | 1635 | int 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; | |
1731 | out: | 1736 | out: |
1732 | kfree(bits); | 1737 | kfree(bits); |
1733 | out_nofds: | 1738 | out_nofds: |