提交 b40ef869 编写于 作者: A Al Viro

saner calling conventions for copy_mount_options()

let it just return NULL, pointer to kernel copy or ERR_PTR().
Signed-off-by: NAl Viro <viro@zeniv.linux.org.uk>
上级 cc4e719e
...@@ -792,7 +792,7 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, ...@@ -792,7 +792,7 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
const void __user *, data) const void __user *, data)
{ {
char *kernel_type; char *kernel_type;
unsigned long data_page; void *options;
char *kernel_dev; char *kernel_dev;
int retval; int retval;
...@@ -806,26 +806,25 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name, ...@@ -806,26 +806,25 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
if (IS_ERR(kernel_dev)) if (IS_ERR(kernel_dev))
goto out1; goto out1;
retval = copy_mount_options(data, &data_page); options = copy_mount_options(data);
if (retval < 0) retval = PTR_ERR(options);
if (IS_ERR(options))
goto out2; goto out2;
retval = -EINVAL; if (kernel_type && options) {
if (kernel_type && data_page) {
if (!strcmp(kernel_type, NCPFS_NAME)) { 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)) { } 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; goto out3;
} }
} }
retval = do_mount(kernel_dev, dir_name, kernel_type, retval = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
flags, (void*)data_page);
out3: out3:
free_page(data_page); kfree(options);
out2: out2:
kfree(kernel_dev); kfree(kernel_dev);
out1: out1:
......
...@@ -55,7 +55,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, ...@@ -55,7 +55,7 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
/* /*
* namespace.c * 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 char *copy_mount_string(const void __user *);
extern struct vfsmount *lookup_mnt(struct path *); extern struct vfsmount *lookup_mnt(struct path *);
......
...@@ -2601,18 +2601,18 @@ static long exact_copy_from_user(void *to, const void __user * from, ...@@ -2601,18 +2601,18 @@ static long exact_copy_from_user(void *to, const void __user * from,
return n; return n;
} }
int copy_mount_options(const void __user * data, unsigned long *where) void *copy_mount_options(const void __user * data)
{ {
int i; int i;
unsigned long page;
unsigned long size; unsigned long size;
char *copy;
*where = 0;
if (!data) if (!data)
return 0; return NULL;
if (!(page = __get_free_page(GFP_KERNEL))) copy = kmalloc(PAGE_SIZE, GFP_KERNEL);
return -ENOMEM; if (!copy)
return ERR_PTR(-ENOMEM);
/* We only care that *some* data at the address the user /* We only care that *some* data at the address the user
* gave us is valid. Just in case, we'll zero * 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) ...@@ -2623,15 +2623,14 @@ int copy_mount_options(const void __user * data, unsigned long *where)
if (size > PAGE_SIZE) if (size > PAGE_SIZE)
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) { if (!i) {
free_page(page); kfree(copy);
return -EFAULT; return ERR_PTR(-EFAULT);
} }
if (i != PAGE_SIZE) if (i != PAGE_SIZE)
memset((char *)page + i, 0, PAGE_SIZE - i); memset(copy + i, 0, PAGE_SIZE - i);
*where = page; return copy;
return 0;
} }
char *copy_mount_string(const void __user *data) char *copy_mount_string(const void __user *data)
...@@ -2896,7 +2895,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, ...@@ -2896,7 +2895,7 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
int ret; int ret;
char *kernel_type; char *kernel_type;
char *kernel_dev; char *kernel_dev;
unsigned long data_page; void *options;
kernel_type = copy_mount_string(type); kernel_type = copy_mount_string(type);
ret = PTR_ERR(kernel_type); ret = PTR_ERR(kernel_type);
...@@ -2908,14 +2907,14 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, ...@@ -2908,14 +2907,14 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
if (IS_ERR(kernel_dev)) if (IS_ERR(kernel_dev))
goto out_dev; goto out_dev;
ret = copy_mount_options(data, &data_page); options = copy_mount_options(data);
if (ret < 0) ret = PTR_ERR(options);
if (IS_ERR(options))
goto out_data; goto out_data;
ret = do_mount(kernel_dev, dir_name, kernel_type, flags, ret = do_mount(kernel_dev, dir_name, kernel_type, flags, options);
(void *) data_page);
free_page(data_page); kfree(options);
out_data: out_data:
kfree(kernel_dev); kfree(kernel_dev);
out_dev: out_dev:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册