diff options
Diffstat (limited to 'fs/compat.c')
| -rw-r--r-- | fs/compat.c | 44 |
1 files changed, 8 insertions, 36 deletions
diff --git a/fs/compat.c b/fs/compat.c index f03abdadc401..c580c322fa6b 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -29,8 +29,6 @@ | |||
| 29 | #include <linux/vfs.h> | 29 | #include <linux/vfs.h> |
| 30 | #include <linux/ioctl.h> | 30 | #include <linux/ioctl.h> |
| 31 | #include <linux/init.h> | 31 | #include <linux/init.h> |
| 32 | #include <linux/smb.h> | ||
| 33 | #include <linux/smb_mount.h> | ||
| 34 | #include <linux/ncp_mount.h> | 32 | #include <linux/ncp_mount.h> |
| 35 | #include <linux/nfs4_mount.h> | 33 | #include <linux/nfs4_mount.h> |
| 36 | #include <linux/syscalls.h> | 34 | #include <linux/syscalls.h> |
| @@ -51,6 +49,7 @@ | |||
| 51 | #include <linux/eventpoll.h> | 49 | #include <linux/eventpoll.h> |
| 52 | #include <linux/fs_struct.h> | 50 | #include <linux/fs_struct.h> |
| 53 | #include <linux/slab.h> | 51 | #include <linux/slab.h> |
| 52 | #include <linux/pagemap.h> | ||
| 54 | 53 | ||
| 55 | #include <asm/uaccess.h> | 54 | #include <asm/uaccess.h> |
| 56 | #include <asm/mmu_context.h> | 55 | #include <asm/mmu_context.h> |
| @@ -608,14 +607,14 @@ ssize_t compat_rw_copy_check_uvector(int type, | |||
| 608 | /* | 607 | /* |
| 609 | * Single unix specification: | 608 | * Single unix specification: |
| 610 | * We should -EINVAL if an element length is not >= 0 and fitting an | 609 | * We should -EINVAL if an element length is not >= 0 and fitting an |
| 611 | * ssize_t. The total length is fitting an ssize_t | 610 | * ssize_t. |
| 612 | * | 611 | * |
| 613 | * Be careful here because iov_len is a size_t not an ssize_t | 612 | * In Linux, the total length is limited to MAX_RW_COUNT, there is |
| 613 | * no overflow possibility. | ||
| 614 | */ | 614 | */ |
| 615 | tot_len = 0; | 615 | tot_len = 0; |
| 616 | ret = -EINVAL; | 616 | ret = -EINVAL; |
| 617 | for (seg = 0; seg < nr_segs; seg++) { | 617 | for (seg = 0; seg < nr_segs; seg++) { |
| 618 | compat_ssize_t tmp = tot_len; | ||
| 619 | compat_uptr_t buf; | 618 | compat_uptr_t buf; |
| 620 | compat_ssize_t len; | 619 | compat_ssize_t len; |
| 621 | 620 | ||
| @@ -626,13 +625,13 @@ ssize_t compat_rw_copy_check_uvector(int type, | |||
| 626 | } | 625 | } |
| 627 | if (len < 0) /* size_t not fitting in compat_ssize_t .. */ | 626 | if (len < 0) /* size_t not fitting in compat_ssize_t .. */ |
| 628 | goto out; | 627 | goto out; |
| 629 | tot_len += len; | ||
| 630 | if (tot_len < tmp) /* maths overflow on the compat_ssize_t */ | ||
| 631 | goto out; | ||
| 632 | if (!access_ok(vrfy_dir(type), compat_ptr(buf), len)) { | 628 | if (!access_ok(vrfy_dir(type), compat_ptr(buf), len)) { |
| 633 | ret = -EFAULT; | 629 | ret = -EFAULT; |
| 634 | goto out; | 630 | goto out; |
| 635 | } | 631 | } |
| 632 | if (len > MAX_RW_COUNT - tot_len) | ||
| 633 | len = MAX_RW_COUNT - tot_len; | ||
| 634 | tot_len += len; | ||
| 636 | iov->iov_base = compat_ptr(buf); | 635 | iov->iov_base = compat_ptr(buf); |
| 637 | iov->iov_len = (compat_size_t) len; | 636 | iov->iov_len = (compat_size_t) len; |
| 638 | uvector++; | 637 | uvector++; |
| @@ -745,30 +744,6 @@ static void *do_ncp_super_data_conv(void *raw_data) | |||
| 745 | return raw_data; | 744 | return raw_data; |
| 746 | } | 745 | } |
| 747 | 746 | ||
| 748 | struct compat_smb_mount_data { | ||
| 749 | compat_int_t version; | ||
| 750 | __compat_uid_t mounted_uid; | ||
| 751 | __compat_uid_t uid; | ||
| 752 | __compat_gid_t gid; | ||
| 753 | compat_mode_t file_mode; | ||
| 754 | compat_mode_t dir_mode; | ||
| 755 | }; | ||
| 756 | |||
| 757 | static void *do_smb_super_data_conv(void *raw_data) | ||
| 758 | { | ||
| 759 | struct smb_mount_data *s = raw_data; | ||
| 760 | struct compat_smb_mount_data *c_s = raw_data; | ||
| 761 | |||
| 762 | if (c_s->version != SMB_MOUNT_OLDVERSION) | ||
| 763 | goto out; | ||
| 764 | s->dir_mode = c_s->dir_mode; | ||
| 765 | s->file_mode = c_s->file_mode; | ||
| 766 | s->gid = c_s->gid; | ||
| 767 | s->uid = c_s->uid; | ||
| 768 | s->mounted_uid = c_s->mounted_uid; | ||
| 769 | out: | ||
| 770 | return raw_data; | ||
| 771 | } | ||
| 772 | 747 | ||
| 773 | struct compat_nfs_string { | 748 | struct compat_nfs_string { |
| 774 | compat_uint_t len; | 749 | compat_uint_t len; |
| @@ -835,7 +810,6 @@ static int do_nfs4_super_data_conv(void *raw_data) | |||
| 835 | return 0; | 810 | return 0; |
| 836 | } | 811 | } |
| 837 | 812 | ||
| 838 | #define SMBFS_NAME "smbfs" | ||
| 839 | #define NCPFS_NAME "ncpfs" | 813 | #define NCPFS_NAME "ncpfs" |
| 840 | #define NFS4_NAME "nfs4" | 814 | #define NFS4_NAME "nfs4" |
| 841 | 815 | ||
| @@ -870,9 +844,7 @@ asmlinkage long compat_sys_mount(const char __user * dev_name, | |||
| 870 | retval = -EINVAL; | 844 | retval = -EINVAL; |
| 871 | 845 | ||
| 872 | if (kernel_type && data_page) { | 846 | if (kernel_type && data_page) { |
| 873 | if (!strcmp(kernel_type, SMBFS_NAME)) { | 847 | if (!strcmp(kernel_type, NCPFS_NAME)) { |
| 874 | do_smb_super_data_conv((void *)data_page); | ||
| 875 | } else if (!strcmp(kernel_type, NCPFS_NAME)) { | ||
| 876 | do_ncp_super_data_conv((void *)data_page); | 848 | do_ncp_super_data_conv((void *)data_page); |
| 877 | } else if (!strcmp(kernel_type, NFS4_NAME)) { | 849 | } else if (!strcmp(kernel_type, NFS4_NAME)) { |
| 878 | if (do_nfs4_super_data_conv((void *) data_page)) | 850 | if (do_nfs4_super_data_conv((void *) data_page)) |
