Loading fs/compat.c +10 −11 Original line number Diff line number Diff line Loading @@ -792,7 +792,7 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, const void __user *, data) { char *kernel_type; unsigned long data_page; void *options; char *kernel_dev; int retval; Loading @@ -806,26 +806,25 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, if (IS_ERR(kernel_dev)) goto out1; retval = copy_mount_options(data, &data_page); if (retval < 0) options = copy_mount_options(data); retval = PTR_ERR(options); if (IS_ERR(options)) goto out2; retval = -EINVAL; if (kernel_type && data_page) { if (kernel_type && options) { if (!strcmp(kernel_type, NCPFS_NAME)) { do_ncp_super_data_conv((void *)data_page); do_ncp_super_data_conv(options); } else if (!strcmp(kernel_type, NFS4_NAME)) { if (do_nfs4_super_data_conv((void *) data_page)) retval = -EINVAL; if (do_nfs4_super_data_conv(options)) goto out3; } } retval = do_mount(kernel_dev, dir_name, kernel_type, flags, (void*)data_page); retval = do_mount(kernel_dev, dir_name, kernel_type, flags, options); out3: free_page(data_page); kfree(options); out2: kfree(kernel_dev); out1: Loading fs/internal.h +1 −1 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, /* * namespace.c */ extern int copy_mount_options(const void __user *, unsigned long *); extern void *copy_mount_options(const void __user *); extern char *copy_mount_string(const void __user *); extern struct vfsmount *lookup_mnt(struct path *); Loading fs/namespace.c +17 −18 Original line number Diff line number Diff line Loading @@ -2601,18 +2601,18 @@ static long exact_copy_from_user(void *to, const void __user * from, return n; } int copy_mount_options(const void __user * data, unsigned long *where) void *copy_mount_options(const void __user * data) { int i; unsigned long page; unsigned long size; char *copy; *where = 0; if (!data) return 0; return NULL; if (!(page = __get_free_page(GFP_KERNEL))) return -ENOMEM; copy = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!copy) return ERR_PTR(-ENOMEM); /* We only care that *some* data at the address the user * gave us is valid. Just in case, we'll zero Loading @@ -2623,15 +2623,14 @@ int copy_mount_options(const void __user * data, unsigned long *where) if (size > PAGE_SIZE) size = PAGE_SIZE; i = size - exact_copy_from_user((void *)page, data, size); i = size - exact_copy_from_user(copy, data, size); if (!i) { free_page(page); return -EFAULT; kfree(copy); return ERR_PTR(-EFAULT); } if (i != PAGE_SIZE) memset((char *)page + i, 0, PAGE_SIZE - i); *where = page; return 0; memset(copy + i, 0, PAGE_SIZE - i); return copy; } char *copy_mount_string(const void __user *data) Loading Loading @@ -2896,7 +2895,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, int ret; char *kernel_type; char *kernel_dev; unsigned long data_page; void *options; kernel_type = copy_mount_string(type); ret = PTR_ERR(kernel_type); Loading @@ -2908,14 +2907,14 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, if (IS_ERR(kernel_dev)) goto out_dev; ret = copy_mount_options(data, &data_page); if (ret < 0) options = copy_mount_options(data); ret = PTR_ERR(options); if (IS_ERR(options)) goto out_data; ret = do_mount(kernel_dev, dir_name, kernel_type, flags, (void *) data_page); ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options); free_page(data_page); kfree(options); out_data: kfree(kernel_dev); out_dev: Loading Loading
fs/compat.c +10 −11 Original line number Diff line number Diff line Loading @@ -792,7 +792,7 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, const void __user *, data) { char *kernel_type; unsigned long data_page; void *options; char *kernel_dev; int retval; Loading @@ -806,26 +806,25 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, if (IS_ERR(kernel_dev)) goto out1; retval = copy_mount_options(data, &data_page); if (retval < 0) options = copy_mount_options(data); retval = PTR_ERR(options); if (IS_ERR(options)) goto out2; retval = -EINVAL; if (kernel_type && data_page) { if (kernel_type && options) { if (!strcmp(kernel_type, NCPFS_NAME)) { do_ncp_super_data_conv((void *)data_page); do_ncp_super_data_conv(options); } else if (!strcmp(kernel_type, NFS4_NAME)) { if (do_nfs4_super_data_conv((void *) data_page)) retval = -EINVAL; if (do_nfs4_super_data_conv(options)) goto out3; } } retval = do_mount(kernel_dev, dir_name, kernel_type, flags, (void*)data_page); retval = do_mount(kernel_dev, dir_name, kernel_type, flags, options); out3: free_page(data_page); kfree(options); out2: kfree(kernel_dev); out1: Loading
fs/internal.h +1 −1 Original line number Diff line number Diff line Loading @@ -55,7 +55,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, /* * namespace.c */ extern int copy_mount_options(const void __user *, unsigned long *); extern void *copy_mount_options(const void __user *); extern char *copy_mount_string(const void __user *); extern struct vfsmount *lookup_mnt(struct path *); Loading
fs/namespace.c +17 −18 Original line number Diff line number Diff line Loading @@ -2601,18 +2601,18 @@ static long exact_copy_from_user(void *to, const void __user * from, return n; } int copy_mount_options(const void __user * data, unsigned long *where) void *copy_mount_options(const void __user * data) { int i; unsigned long page; unsigned long size; char *copy; *where = 0; if (!data) return 0; return NULL; if (!(page = __get_free_page(GFP_KERNEL))) return -ENOMEM; copy = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!copy) return ERR_PTR(-ENOMEM); /* We only care that *some* data at the address the user * gave us is valid. Just in case, we'll zero Loading @@ -2623,15 +2623,14 @@ int copy_mount_options(const void __user * data, unsigned long *where) if (size > PAGE_SIZE) size = PAGE_SIZE; i = size - exact_copy_from_user((void *)page, data, size); i = size - exact_copy_from_user(copy, data, size); if (!i) { free_page(page); return -EFAULT; kfree(copy); return ERR_PTR(-EFAULT); } if (i != PAGE_SIZE) memset((char *)page + i, 0, PAGE_SIZE - i); *where = page; return 0; memset(copy + i, 0, PAGE_SIZE - i); return copy; } char *copy_mount_string(const void __user *data) Loading Loading @@ -2896,7 +2895,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, int ret; char *kernel_type; char *kernel_dev; unsigned long data_page; void *options; kernel_type = copy_mount_string(type); ret = PTR_ERR(kernel_type); Loading @@ -2908,14 +2907,14 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, if (IS_ERR(kernel_dev)) goto out_dev; ret = copy_mount_options(data, &data_page); if (ret < 0) options = copy_mount_options(data); ret = PTR_ERR(options); if (IS_ERR(options)) goto out_data; ret = do_mount(kernel_dev, dir_name, kernel_type, flags, (void *) data_page); ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options); free_page(data_page); kfree(options); out_data: kfree(kernel_dev); out_dev: Loading