Merge branch 'mount.part1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[sfrench/cifs-2.6.git] / fs / nfs / super.c
index ac4b2f005778c05df1bb68117f66fd407f20a529..22ce3c8a2f463dd64dfba9877baa9071f3e63e22 100644 (file)
@@ -929,7 +929,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
                data->minorversion      = 0;
                data->need_mount        = true;
                data->net               = current->nsproxy->net_ns;
-               security_init_mnt_opts(&data->lsm_opts);
+               data->lsm_opts          = NULL;
        }
        return data;
 }
@@ -1206,7 +1206,7 @@ static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option,
 static int nfs_parse_mount_options(char *raw,
                                   struct nfs_parsed_mount_data *mnt)
 {
-       char *p, *string, *secdata;
+       char *p, *string;
        int rc, sloppy = 0, invalid_option = 0;
        unsigned short protofamily = AF_UNSPEC;
        unsigned short mountfamily = AF_UNSPEC;
@@ -1217,20 +1217,10 @@ static int nfs_parse_mount_options(char *raw,
        }
        dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
 
-       secdata = alloc_secdata();
-       if (!secdata)
-               goto out_nomem;
-
-       rc = security_sb_copy_data(raw, secdata);
-       if (rc)
-               goto out_security_failure;
-
-       rc = security_sb_parse_opts_str(secdata, &mnt->lsm_opts);
+       rc = security_sb_eat_lsm_opts(raw, &mnt->lsm_opts);
        if (rc)
                goto out_security_failure;
 
-       free_secdata(secdata);
-
        while ((p = strsep(&raw, ",")) != NULL) {
                substring_t args[MAX_OPT_ARGS];
                unsigned long option;
@@ -1682,7 +1672,6 @@ out_nomem:
        printk(KERN_INFO "NFS: not enough memory to parse option\n");
        return 0;
 out_security_failure:
-       free_secdata(secdata);
        printk(KERN_INFO "NFS: security options invalid: %d\n", rc);
        return 0;
 }
@@ -2081,14 +2070,9 @@ static int nfs23_validate_mount_data(void *options,
                if (data->context[0]){
 #ifdef CONFIG_SECURITY_SELINUX
                        int rc;
-                       char *opts_str = kmalloc(sizeof(data->context) + 8, GFP_KERNEL);
-                       if (!opts_str)
-                               return -ENOMEM;
-                       strcpy(opts_str, "context=");
                        data->context[NFS_MAX_CONTEXT_LEN] = '\0';
-                       strcat(opts_str, &data->context[0]);
-                       rc = security_sb_parse_opts_str(opts_str, &args->lsm_opts);
-                       kfree(opts_str);
+                       rc = security_add_mnt_opt("context", data->context,
+                                       strlen(data->context), &args->lsm_opts);
                        if (rc)
                                return rc;
 #else
@@ -2168,7 +2152,10 @@ static int nfs_validate_text_mount_data(void *options,
 
        if (args->version == 4) {
 #if IS_ENABLED(CONFIG_NFS_V4)
-               port = NFS_PORT;
+               if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
+                       port = NFS_RDMA_PORT;
+               else
+                       port = NFS_PORT;
                max_namelen = NFS4_MAXNAMLEN;
                max_pathlen = NFS4_MAXPATHLEN;
                nfs_validate_transport_protocol(args);
@@ -2178,8 +2165,11 @@ static int nfs_validate_text_mount_data(void *options,
 #else
                goto out_v4_not_compiled;
 #endif /* CONFIG_NFS_V4 */
-       } else
+       } else {
                nfs_set_mount_transport_protocol(args);
+               if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
+                       port = NFS_RDMA_PORT;
+       }
 
        nfs_set_port(sap, &args->nfs_server.port, port);
 
@@ -2265,7 +2255,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
                                           options->version <= 6))))
                return 0;
 
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       data = nfs_alloc_parsed_mount_data();
        if (data == NULL)
                return -ENOMEM;
 
@@ -2304,8 +2294,10 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
 
        /* compare new mount options with old ones */
        error = nfs_compare_remount_data(nfss, data);
+       if (!error)
+               error = security_sb_remount(sb, data->lsm_opts);
 out:
-       kfree(data);
+       nfs_free_parsed_mount_data(data);
        return error;
 }
 EXPORT_SYMBOL_GPL(nfs_remount);
@@ -2409,8 +2401,7 @@ static int nfs_compare_mount_options(const struct super_block *s, const struct n
                goto Ebusy;
        if (a->acdirmax != b->acdirmax)
                goto Ebusy;
-       if (b->auth_info.flavor_len > 0 &&
-          clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
+       if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
                goto Ebusy;
        return 1;
 Ebusy:
@@ -2543,7 +2534,7 @@ int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
        if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
                kflags |= SECURITY_LSM_NATIVE_LABELS;
 
-       error = security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts,
+       error = security_sb_set_mnt_opts(s, mount_info->parsed->lsm_opts,
                                                kflags, &kflags_out);
        if (error)
                goto err;