aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeunghun Lee <waydi1@gmail.com>2014-09-14 09:15:10 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-10-09 02:39:16 -0400
commit5e6123f3477e4260fb14392f0a88f1a842fa4d42 (patch)
tree66cf4572317d0e634f169cbdc702e773fe0e4b5c
parent4d93bc3e81736ce55c79d9cae743bab4f89b4f9c (diff)
vfs: move getname() from callers to do_mount()
It would make more sense to pass char __user * instead of char * in callers of do_mount() and do getname() inside do_mount(). Suggested-by: Al Viro <viro@ZenIV.linux.org.uk> Signed-off-by: Seunghun Lee <waydi1@gmail.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--arch/alpha/kernel/osf_sys.c23
-rw-r--r--fs/compat.c20
-rw-r--r--fs/namespace.c19
-rw-r--r--include/linux/fs.h3
4 files changed, 21 insertions, 44 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 1402fcc11c2c..f9c732e18284 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -446,7 +446,8 @@ struct procfs_args {
446 * unhappy with OSF UFS. [CHECKME] 446 * unhappy with OSF UFS. [CHECKME]
447 */ 447 */
448static int 448static int
449osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags) 449osf_ufs_mount(const char __user *dirname,
450 struct ufs_args __user *args, int flags)
450{ 451{
451 int retval; 452 int retval;
452 struct cdfs_args tmp; 453 struct cdfs_args tmp;
@@ -466,7 +467,8 @@ osf_ufs_mount(const char *dirname, struct ufs_args __user *args, int flags)
466} 467}
467 468
468static int 469static int
469osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags) 470osf_cdfs_mount(const char __user *dirname,
471 struct cdfs_args __user *args, int flags)
470{ 472{
471 int retval; 473 int retval;
472 struct cdfs_args tmp; 474 struct cdfs_args tmp;
@@ -486,7 +488,8 @@ osf_cdfs_mount(const char *dirname, struct cdfs_args __user *args, int flags)
486} 488}
487 489
488static int 490static int
489osf_procfs_mount(const char *dirname, struct procfs_args __user *args, int flags) 491osf_procfs_mount(const char __user *dirname,
492 struct procfs_args __user *args, int flags)
490{ 493{
491 struct procfs_args tmp; 494 struct procfs_args tmp;
492 495
@@ -500,28 +503,22 @@ SYSCALL_DEFINE4(osf_mount, unsigned long, typenr, const char __user *, path,
500 int, flag, void __user *, data) 503 int, flag, void __user *, data)
501{ 504{
502 int retval; 505 int retval;
503 struct filename *name;
504 506
505 name = getname(path);
506 retval = PTR_ERR(name);
507 if (IS_ERR(name))
508 goto out;
509 switch (typenr) { 507 switch (typenr) {
510 case 1: 508 case 1:
511 retval = osf_ufs_mount(name->name, data, flag); 509 retval = osf_ufs_mount(path, data, flag);
512 break; 510 break;
513 case 6: 511 case 6:
514 retval = osf_cdfs_mount(name->name, data, flag); 512 retval = osf_cdfs_mount(path, data, flag);
515 break; 513 break;
516 case 9: 514 case 9:
517 retval = osf_procfs_mount(name->name, data, flag); 515 retval = osf_procfs_mount(path, data, flag);
518 break; 516 break;
519 default: 517 default:
520 retval = -EINVAL; 518 retval = -EINVAL;
521 printk("osf_mount(%ld, %x)\n", typenr, flag); 519 printk("osf_mount(%ld, %x)\n", typenr, flag);
522 } 520 }
523 putname(name); 521
524 out:
525 return retval; 522 return retval;
526} 523}
527 524
diff --git a/fs/compat.c b/fs/compat.c
index 6205c247a6e3..b13df99f3534 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -794,7 +794,6 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
794 char *kernel_type; 794 char *kernel_type;
795 unsigned long data_page; 795 unsigned long data_page;
796 char *kernel_dev; 796 char *kernel_dev;
797 struct filename *dir;
798 int retval; 797 int retval;
799 798
800 kernel_type = copy_mount_string(type); 799 kernel_type = copy_mount_string(type);
@@ -802,19 +801,14 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
802 if (IS_ERR(kernel_type)) 801 if (IS_ERR(kernel_type))
803 goto out; 802 goto out;
804 803
805 dir = getname(dir_name);
806 retval = PTR_ERR(dir);
807 if (IS_ERR(dir))
808 goto out1;
809
810 kernel_dev = copy_mount_string(dev_name); 804 kernel_dev = copy_mount_string(dev_name);
811 retval = PTR_ERR(kernel_dev); 805 retval = PTR_ERR(kernel_dev);
812 if (IS_ERR(kernel_dev)) 806 if (IS_ERR(kernel_dev))
813 goto out2; 807 goto out1;
814 808
815 retval = copy_mount_options(data, &data_page); 809 retval = copy_mount_options(data, &data_page);
816 if (retval < 0) 810 if (retval < 0)
817 goto out3; 811 goto out2;
818 812
819 retval = -EINVAL; 813 retval = -EINVAL;
820 814
@@ -823,19 +817,17 @@ COMPAT_SYSCALL_DEFINE5(mount, const char __user *, dev_name,
823 do_ncp_super_data_conv((void *)data_page); 817 do_ncp_super_data_conv((void *)data_page);
824 } else if (!strcmp(kernel_type, NFS4_NAME)) { 818 } else if (!strcmp(kernel_type, NFS4_NAME)) {
825 if (do_nfs4_super_data_conv((void *) data_page)) 819 if (do_nfs4_super_data_conv((void *) data_page))
826 goto out4; 820 goto out3;
827 } 821 }
828 } 822 }
829 823
830 retval = do_mount(kernel_dev, dir->name, kernel_type, 824 retval = do_mount(kernel_dev, dir_name, kernel_type,
831 flags, (void*)data_page); 825 flags, (void*)data_page);
832 826
833 out4:
834 free_page(data_page);
835 out3: 827 out3:
836 kfree(kernel_dev); 828 free_page(data_page);
837 out2: 829 out2:
838 putname(dir); 830 kfree(kernel_dev);
839 out1: 831 out1:
840 kfree(kernel_type); 832 kfree(kernel_type);
841 out: 833 out:
diff --git a/fs/namespace.c b/fs/namespace.c
index abd3abb52616..348562f14e93 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2533,7 +2533,7 @@ char *copy_mount_string(const void __user *data)
2533 * Therefore, if this magic number is present, it carries no information 2533 * Therefore, if this magic number is present, it carries no information
2534 * and must be discarded. 2534 * and must be discarded.
2535 */ 2535 */
2536long do_mount(const char *dev_name, const char *dir_name, 2536long do_mount(const char *dev_name, const char __user *dir_name,
2537 const char *type_page, unsigned long flags, void *data_page) 2537 const char *type_page, unsigned long flags, void *data_page)
2538{ 2538{
2539 struct path path; 2539 struct path path;
@@ -2545,15 +2545,11 @@ long do_mount(const char *dev_name, const char *dir_name,
2545 flags &= ~MS_MGC_MSK; 2545 flags &= ~MS_MGC_MSK;
2546 2546
2547 /* Basic sanity checks */ 2547 /* Basic sanity checks */
2548
2549 if (!dir_name || !*dir_name || !memchr(dir_name, 0, PAGE_SIZE))
2550 return -EINVAL;
2551
2552 if (data_page) 2548 if (data_page)
2553 ((char *)data_page)[PAGE_SIZE - 1] = 0; 2549 ((char *)data_page)[PAGE_SIZE - 1] = 0;
2554 2550
2555 /* ... and get the mountpoint */ 2551 /* ... and get the mountpoint */
2556 retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); 2552 retval = user_path(dir_name, &path);
2557 if (retval) 2553 if (retval)
2558 return retval; 2554 return retval;
2559 2555
@@ -2778,7 +2774,6 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
2778{ 2774{
2779 int ret; 2775 int ret;
2780 char *kernel_type; 2776 char *kernel_type;
2781 struct filename *kernel_dir;
2782 char *kernel_dev; 2777 char *kernel_dev;
2783 unsigned long data_page; 2778 unsigned long data_page;
2784 2779
@@ -2787,12 +2782,6 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
2787 if (IS_ERR(kernel_type)) 2782 if (IS_ERR(kernel_type))
2788 goto out_type; 2783 goto out_type;
2789 2784
2790 kernel_dir = getname(dir_name);
2791 if (IS_ERR(kernel_dir)) {
2792 ret = PTR_ERR(kernel_dir);
2793 goto out_dir;
2794 }
2795
2796 kernel_dev = copy_mount_string(dev_name); 2785 kernel_dev = copy_mount_string(dev_name);
2797 ret = PTR_ERR(kernel_dev); 2786 ret = PTR_ERR(kernel_dev);
2798 if (IS_ERR(kernel_dev)) 2787 if (IS_ERR(kernel_dev))
@@ -2802,15 +2791,13 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
2802 if (ret < 0) 2791 if (ret < 0)
2803 goto out_data; 2792 goto out_data;
2804 2793
2805 ret = do_mount(kernel_dev, kernel_dir->name, kernel_type, flags, 2794 ret = do_mount(kernel_dev, dir_name, kernel_type, flags,
2806 (void *) data_page); 2795 (void *) data_page);
2807 2796
2808 free_page(data_page); 2797 free_page(data_page);
2809out_data: 2798out_data:
2810 kfree(kernel_dev); 2799 kfree(kernel_dev);
2811out_dev: 2800out_dev:
2812 putname(kernel_dir);
2813out_dir:
2814 kfree(kernel_type); 2801 kfree(kernel_type);
2815out_type: 2802out_type:
2816 return ret; 2803 return ret;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 75bdd51ec9b8..92148361bef8 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1855,7 +1855,8 @@ extern struct vfsmount *kern_mount_data(struct file_system_type *, void *data);
1855extern void kern_unmount(struct vfsmount *mnt); 1855extern void kern_unmount(struct vfsmount *mnt);
1856extern int may_umount_tree(struct vfsmount *); 1856extern int may_umount_tree(struct vfsmount *);
1857extern int may_umount(struct vfsmount *); 1857extern int may_umount(struct vfsmount *);
1858extern long do_mount(const char *, const char *, const char *, unsigned long, void *); 1858extern long do_mount(const char *, const char __user *,
1859 const char *, unsigned long, void *);
1859extern struct vfsmount *collect_mounts(struct path *); 1860extern struct vfsmount *collect_mounts(struct path *);
1860extern void drop_collected_mounts(struct vfsmount *); 1861extern void drop_collected_mounts(struct vfsmount *);
1861extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *, 1862extern int iterate_mounts(int (*)(struct vfsmount *, void *), void *,