diff options
-rw-r--r-- | fs/nfs/super.c | 53 |
1 files changed, 16 insertions, 37 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index e7d197085834..04ad881eac77 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -785,27 +785,6 @@ static void nfs4_fill_super(struct super_block *sb) | |||
785 | nfs_initialise_sb(sb); | 785 | nfs_initialise_sb(sb); |
786 | } | 786 | } |
787 | 787 | ||
788 | static void *nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen) | ||
789 | { | ||
790 | void *p = NULL; | ||
791 | |||
792 | if (!src->len) | ||
793 | return ERR_PTR(-EINVAL); | ||
794 | if (src->len < maxlen) | ||
795 | maxlen = src->len; | ||
796 | if (dst == NULL) { | ||
797 | p = dst = kmalloc(maxlen + 1, GFP_KERNEL); | ||
798 | if (p == NULL) | ||
799 | return ERR_PTR(-ENOMEM); | ||
800 | } | ||
801 | if (copy_from_user(dst, src->data, maxlen)) { | ||
802 | kfree(p); | ||
803 | return ERR_PTR(-EFAULT); | ||
804 | } | ||
805 | dst[maxlen] = '\0'; | ||
806 | return dst; | ||
807 | } | ||
808 | |||
809 | /* | 788 | /* |
810 | * Get the superblock for an NFS4 mountpoint | 789 | * Get the superblock for an NFS4 mountpoint |
811 | */ | 790 | */ |
@@ -819,8 +798,7 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
819 | rpc_authflavor_t authflavour; | 798 | rpc_authflavor_t authflavour; |
820 | struct nfs_fh mntfh; | 799 | struct nfs_fh mntfh; |
821 | struct dentry *mntroot; | 800 | struct dentry *mntroot; |
822 | char *mntpath = NULL, *hostname = NULL, ip_addr[16]; | 801 | char *p, *mntpath = NULL, *hostname = NULL, *ip_addr = NULL; |
823 | void *p; | ||
824 | int error; | 802 | int error; |
825 | 803 | ||
826 | if (data == NULL) { | 804 | if (data == NULL) { |
@@ -857,39 +835,39 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
857 | dprintk("%s: Invalid number of RPC auth flavours %d.\n", | 835 | dprintk("%s: Invalid number of RPC auth flavours %d.\n", |
858 | __FUNCTION__, data->auth_flavourlen); | 836 | __FUNCTION__, data->auth_flavourlen); |
859 | error = -EINVAL; | 837 | error = -EINVAL; |
860 | goto out_err_noserver; | 838 | goto out; |
861 | } | 839 | } |
862 | 840 | ||
863 | if (copy_from_user(&authflavour, data->auth_flavours, | 841 | if (copy_from_user(&authflavour, data->auth_flavours, |
864 | sizeof(authflavour))) { | 842 | sizeof(authflavour))) { |
865 | error = -EFAULT; | 843 | error = -EFAULT; |
866 | goto out_err_noserver; | 844 | goto out; |
867 | } | 845 | } |
868 | } | 846 | } |
869 | 847 | ||
870 | p = nfs_copy_user_string(NULL, &data->hostname, NFS4_MAXNAMLEN); | 848 | p = strndup_user(data->hostname.data, NFS4_MAXNAMLEN); |
871 | if (IS_ERR(p)) | 849 | if (IS_ERR(p)) |
872 | goto out_err; | 850 | goto out_err; |
873 | hostname = p; | 851 | hostname = p; |
874 | 852 | ||
875 | p = nfs_copy_user_string(NULL, &data->mnt_path, NFS4_MAXPATHLEN); | 853 | p = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN); |
876 | if (IS_ERR(p)) | 854 | if (IS_ERR(p)) |
877 | goto out_err; | 855 | goto out_err; |
878 | mntpath = p; | 856 | mntpath = p; |
879 | 857 | ||
880 | dprintk("MNTPATH: %s\n", mntpath); | 858 | dprintk("MNTPATH: %s\n", mntpath); |
881 | 859 | ||
882 | p = nfs_copy_user_string(ip_addr, &data->client_addr, | 860 | p = strndup_user(data->client_addr.data, 16); |
883 | sizeof(ip_addr) - 1); | ||
884 | if (IS_ERR(p)) | 861 | if (IS_ERR(p)) |
885 | goto out_err; | 862 | goto out_err; |
863 | ip_addr = p; | ||
886 | 864 | ||
887 | /* Get a volume representation */ | 865 | /* Get a volume representation */ |
888 | server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr, | 866 | server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr, |
889 | authflavour, &mntfh); | 867 | authflavour, &mntfh); |
890 | if (IS_ERR(server)) { | 868 | if (IS_ERR(server)) { |
891 | error = PTR_ERR(server); | 869 | error = PTR_ERR(server); |
892 | goto out_err_noserver; | 870 | goto out; |
893 | } | 871 | } |
894 | 872 | ||
895 | /* Get a superblock - note that we may end up sharing one that already exists */ | 873 | /* Get a superblock - note that we may end up sharing one that already exists */ |
@@ -919,25 +897,26 @@ static int nfs4_get_sb(struct file_system_type *fs_type, | |||
919 | s->s_flags |= MS_ACTIVE; | 897 | s->s_flags |= MS_ACTIVE; |
920 | mnt->mnt_sb = s; | 898 | mnt->mnt_sb = s; |
921 | mnt->mnt_root = mntroot; | 899 | mnt->mnt_root = mntroot; |
900 | error = 0; | ||
901 | |||
902 | out: | ||
903 | kfree(ip_addr); | ||
922 | kfree(mntpath); | 904 | kfree(mntpath); |
923 | kfree(hostname); | 905 | kfree(hostname); |
924 | return 0; | 906 | return error; |
925 | 907 | ||
926 | out_err: | 908 | out_err: |
927 | error = PTR_ERR(p); | 909 | error = PTR_ERR(p); |
928 | goto out_err_noserver; | 910 | goto out; |
929 | 911 | ||
930 | out_free: | 912 | out_free: |
931 | nfs_free_server(server); | 913 | nfs_free_server(server); |
932 | out_err_noserver: | 914 | goto out; |
933 | kfree(mntpath); | ||
934 | kfree(hostname); | ||
935 | return error; | ||
936 | 915 | ||
937 | error_splat_super: | 916 | error_splat_super: |
938 | up_write(&s->s_umount); | 917 | up_write(&s->s_umount); |
939 | deactivate_super(s); | 918 | deactivate_super(s); |
940 | goto out_err_noserver; | 919 | goto out; |
941 | } | 920 | } |
942 | 921 | ||
943 | static void nfs4_kill_super(struct super_block *sb) | 922 | static void nfs4_kill_super(struct super_block *sb) |