Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 165876
b: refs/heads/master
c: eca6f53
h: refs/heads/master
v: v3
  • Loading branch information
Vegard Nossum authored and al committed Sep 24, 2009
1 parent c618c64 commit 16895fd
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6d729e44a55547c009d7a87ea66bff21a8e0afea
refs/heads/master: eca6f534e61919b28fb21aafbd1c2983deae75be
24 changes: 12 additions & 12 deletions trunk/fs/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -768,13 +768,13 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
char __user * type, unsigned long flags,
void __user * data)
{
unsigned long type_page;
char *kernel_type;
unsigned long data_page;
unsigned long dev_page;
char *kernel_dev;
char *dir_page;
int retval;

retval = copy_mount_options (type, &type_page);
retval = copy_mount_string(type, &kernel_type);
if (retval < 0)
goto out;

Expand All @@ -783,38 +783,38 @@ asmlinkage long compat_sys_mount(char __user * dev_name, char __user * dir_name,
if (IS_ERR(dir_page))
goto out1;

retval = copy_mount_options (dev_name, &dev_page);
retval = copy_mount_string(dev_name, &kernel_dev);
if (retval < 0)
goto out2;

retval = copy_mount_options (data, &data_page);
retval = copy_mount_options(data, &data_page);
if (retval < 0)
goto out3;

retval = -EINVAL;

if (type_page && data_page) {
if (!strcmp((char *)type_page, SMBFS_NAME)) {
if (kernel_type && data_page) {
if (!strcmp(kernel_type, SMBFS_NAME)) {
do_smb_super_data_conv((void *)data_page);
} else if (!strcmp((char *)type_page, NCPFS_NAME)) {
} else if (!strcmp(kernel_type, NCPFS_NAME)) {
do_ncp_super_data_conv((void *)data_page);
} else if (!strcmp((char *)type_page, NFS4_NAME)) {
} else if (!strcmp(kernel_type, NFS4_NAME)) {
if (do_nfs4_super_data_conv((void *) data_page))
goto out4;
}
}

retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
retval = do_mount(kernel_dev, dir_page, kernel_type,
flags, (void*)data_page);

out4:
free_page(data_page);
out3:
free_page(dev_page);
kfree(kernel_dev);
out2:
putname(dir_page);
out1:
free_page(type_page);
kfree(kernel_type);
out:
return retval;
}
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ extern int check_unsafe_exec(struct linux_binprm *);
* namespace.c
*/
extern int copy_mount_options(const void __user *, unsigned long *);
extern int copy_mount_string(const void __user *, char **);

extern void free_vfsmnt(struct vfsmount *);
extern struct vfsmount *alloc_vfsmnt(const char *);
Expand Down
77 changes: 47 additions & 30 deletions trunk/fs/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1640,7 +1640,7 @@ static int do_new_mount(struct path *path, char *type, int flags,
{
struct vfsmount *mnt;

if (!type || !memchr(type, 0, PAGE_SIZE))
if (!type)
return -EINVAL;

/* we need capabilities... */
Expand Down Expand Up @@ -1871,6 +1871,23 @@ int copy_mount_options(const void __user * data, unsigned long *where)
return 0;
}

int copy_mount_string(const void __user *data, char **where)
{
char *tmp;

if (!data) {
*where = NULL;
return 0;
}

tmp = strndup_user(data, PAGE_SIZE);
if (IS_ERR(tmp))
return PTR_ERR(tmp);

*where = tmp;
return 0;
}

/*
* Flags is a 32-bit value that allows up to 31 non-fs dependent flags to
* be given to the mount() call (ie: read-only, no-dev, no-suid etc).
Expand Down Expand Up @@ -1900,8 +1917,6 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,

if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE))
return -EINVAL;
if (dev_name && !memchr(dev_name, 0, PAGE_SIZE))
return -EINVAL;

if (data_page)
((char *)data_page)[PAGE_SIZE - 1] = 0;
Expand Down Expand Up @@ -2070,40 +2085,42 @@ EXPORT_SYMBOL(create_mnt_ns);
SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
char __user *, type, unsigned long, flags, void __user *, data)
{
int retval;
int ret;
char *kernel_type;
char *kernel_dir;
char *kernel_dev;
unsigned long data_page;
unsigned long type_page;
unsigned long dev_page;
char *dir_page;

retval = copy_mount_options(type, &type_page);
if (retval < 0)
return retval;
ret = copy_mount_string(type, &kernel_type);
if (ret < 0)
goto out_type;

dir_page = getname(dir_name);
retval = PTR_ERR(dir_page);
if (IS_ERR(dir_page))
goto out1;
kernel_dir = getname(dir_name);
if (IS_ERR(kernel_dir)) {
ret = PTR_ERR(kernel_dir);
goto out_dir;
}

retval = copy_mount_options(dev_name, &dev_page);
if (retval < 0)
goto out2;
ret = copy_mount_string(dev_name, &kernel_dev);
if (ret < 0)
goto out_dev;

retval = copy_mount_options(data, &data_page);
if (retval < 0)
goto out3;
ret = copy_mount_options(data, &data_page);
if (ret < 0)
goto out_data;

retval = do_mount((char *)dev_page, dir_page, (char *)type_page,
flags, (void *)data_page);
free_page(data_page);
ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags,
(void *) data_page);

out3:
free_page(dev_page);
out2:
putname(dir_page);
out1:
free_page(type_page);
return retval;
free_page(data_page);
out_data:
kfree(kernel_dev);
out_dev:
putname(kernel_dir);
out_dir:
kfree(kernel_type);
out_type:
return ret;
}

/*
Expand Down

0 comments on commit 16895fd

Please sign in to comment.