saner calling conventions for copy_mount_options()
authorAl Viro <viro@zeniv.linux.org.uk>
Mon, 14 Dec 2015 23:44:44 +0000 (18:44 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 4 Jan 2016 15:28:32 +0000 (10:28 -0500)
let it just return NULL, pointer to kernel copy or ERR_PTR().

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/compat.c
fs/internal.h
fs/namespace.c

index 6fd272d455e4deb1112c277fc564324fd9d7b3ba..a71936a3f4cb39e7022d98363a0df70d69c8c3d0 100644 (file)
@@ -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;
 
@@ -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:
index 71859c4d0b41b820dfe22bca4d30d8863ad86df7..aa81316aaf47e0d1e074019e20f42d6d9e085261 100644 (file)
@@ -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 *);
index b27156f2e68b74ef0f5e050d7bf16e118d979823..33a75c8e9fcbcad1a77f50bb4706432aff57bb24 100644 (file)
@@ -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
@@ -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)
@@ -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);
@@ -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: