diff options
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 61 |
1 files changed, 10 insertions, 51 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 2fd0c8bcb8c1..85b5f7bea82e 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1728,7 +1728,7 @@ static bool is_mnt_ns_file(struct dentry *dentry) dentry->d_fsdata == &mntns_operations; } -struct mnt_namespace *to_mnt_ns(struct ns_common *ns) +static struct mnt_namespace *to_mnt_ns(struct ns_common *ns) { return container_of(ns, struct mnt_namespace, ns); } @@ -2979,39 +2979,10 @@ static void shrink_submounts(struct mount *mnt) } } -/* - * Some copy_from_user() implementations do not return the exact number of - * bytes remaining to copy on a fault. But copy_mount_options() requires that. - * Note that this function differs from copy_from_user() in that it will oops - * on bad values of `to', rather than returning a short copy. - */ -static long exact_copy_from_user(void *to, const void __user * from, - unsigned long n) -{ - char *t = to; - const char __user *f = from; - char c; - - if (!access_ok(from, n)) - return n; - - while (n) { - if (__get_user(c, f)) { - memset(t, 0, n); - break; - } - *t++ = c; - f++; - n--; - } - return n; -} - void *copy_mount_options(const void __user * data) { - int i; - unsigned long size; char *copy; + unsigned size; if (!data) return NULL; @@ -3020,22 +2991,16 @@ void *copy_mount_options(const void __user * data) 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 - * the remainder of the page. - */ - /* copy_from_user cannot cross TASK_SIZE ! */ - size = TASK_SIZE - (unsigned long)untagged_addr(data); - if (size > PAGE_SIZE) - size = PAGE_SIZE; + size = PAGE_SIZE - offset_in_page(data); - i = size - exact_copy_from_user(copy, data, size); - if (!i) { + if (copy_from_user(copy, data, size)) { kfree(copy); return ERR_PTR(-EFAULT); } - if (i != PAGE_SIZE) - memset(copy + i, 0, PAGE_SIZE - i); + if (size != PAGE_SIZE) { + if (copy_from_user(copy + size, data + size, PAGE_SIZE - size)) + memset(copy + size, 0, PAGE_SIZE - size); + } return copy; } @@ -3325,8 +3290,8 @@ struct dentry *mount_subtree(struct vfsmount *m, const char *name) } EXPORT_SYMBOL(mount_subtree); -int ksys_mount(const char __user *dev_name, const char __user *dir_name, - const char __user *type, unsigned long flags, void __user *data) +SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, + char __user *, type, unsigned long, flags, void __user *, data) { int ret; char *kernel_type; @@ -3359,12 +3324,6 @@ out_type: return ret; } -SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, - char __user *, type, unsigned long, flags, void __user *, data) -{ - return ksys_mount(dev_name, dir_name, type, flags, data); -} - /* * Create a kernel mount representation for a new, prepared superblock * (specified by fs_fd) and attach to an open_tree-like file descriptor. |