Commit b40ef869 authored by Al Viro's avatar Al Viro
Browse files

saner calling conventions for copy_mount_options()



let it just return NULL, pointer to kernel copy or ERR_PTR().

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent cc4e719e
Loading
Loading
Loading
Loading
+10 −11
Original line number Diff line number Diff line
@@ -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:
+1 −1
Original line number Diff line number Diff line
@@ -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 *);
+17 −18
Original line number Diff line number Diff line
@@ -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: