diff options
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 4d2c8f64b7bf..a830e1463704 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2609,18 +2609,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 @@ -2631,15 +2631,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) @@ -2906,7 +2905,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); @@ -2918,14 +2917,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: @@ -2949,9 +2948,9 @@ bool is_path_reachable(struct mount *mnt, struct dentry *dentry, return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry); } -int path_is_under(struct path *path1, struct path *path2) +bool path_is_under(struct path *path1, struct path *path2) { - int res; + bool res; read_seqlock_excl(&mount_lock); res = is_path_reachable(real_mount(path1->mnt), path1->dentry, path2); read_sequnlock_excl(&mount_lock); |