[PATCH v2 2/2] NFSv4 account for selinux security context when deciding to share superblock

Casey Schaufler casey at schaufler-ca.com
Thu Feb 18 22:07:05 UTC 2021


On 2/18/2021 11:50 AM, Olga Kornievskaia wrote:
> From: Olga Kornievskaia <kolga at netapp.com>
>
> Keep track of whether or not there was an selinux context mount
> options during the mount.

This may be the intention, but it's not what the change you're
introducing here does.


>  While deciding if the superblock can be
> shared for the new mount, check for if we had selinux context on
> the existing mount and call into selinux to tell if new passed
> in selinux context is compatible with the existing mount's options.

You're describing how you expect the change to be used, not
what it does. If I am the author of a security module other
than SELinux (which, it turns out, I am) what would I use this
for? How might this change interact with my security module?
Is this something I might exploit? If I am the author of a
filesystem other than NFS (which I am not) should I be doing
the same thing?

>
> Previously, NFS wasn't able to do the following 2mounts:
> mount -o vers=4.2,sec=sys,context=system_u:object_r:root_t:s0
> <serverip>:/ /mnt
> mount -o vers=4.2,sec=sys,context=system_u:object_r:swapfile_t:s0
> <serverip>:/scratch /scratch
>
> 2nd mount would fail with "mount.nfs: an incorrect mount option was
> specified" and var log messages would have:
> "SElinux: mount invalid. Same superblock, different security
> settings for.."
>
> Signed-off-by: Olga Kornievskaia <kolga at netapp.com>
> ---
>  fs/nfs/fs_context.c       | 3 +++
>  fs/nfs/internal.h         | 1 +
>  fs/nfs/super.c            | 4 ++++
>  include/linux/nfs_fs_sb.h | 1 +
>  4 files changed, 9 insertions(+)
>
> diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c
> index 06894bcdea2d..8067f055d842 100644
> --- a/fs/nfs/fs_context.c
> +++ b/fs/nfs/fs_context.c
> @@ -448,6 +448,9 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
>  	if (opt < 0)
>  		return ctx->sloppy ? 1 : opt;
>  
> +	if (fc->security)
> +		ctx->has_sec_mnt_opts = 1;
> +
>  	switch (opt) {
>  	case Opt_source:
>  		if (fc->source)
> diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
> index 62d3189745cd..08f4f34e8cf5 100644
> --- a/fs/nfs/internal.h
> +++ b/fs/nfs/internal.h
> @@ -96,6 +96,7 @@ struct nfs_fs_context {
>  	char			*fscache_uniq;
>  	unsigned short		protofamily;
>  	unsigned short		mountfamily;
> +	bool			has_sec_mnt_opts;
>  
>  	struct {
>  		union {
> diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> index 4034102010f0..0a2d252cf90f 100644
> --- a/fs/nfs/super.c
> +++ b/fs/nfs/super.c
> @@ -1058,6 +1058,7 @@ static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx)
>  						 &sb->s_blocksize_bits);
>  
>  	nfs_super_set_maxbytes(sb, server->maxfilesize);
> +	server->has_sec_mnt_opts = ctx->has_sec_mnt_opts;
>  }
>  
>  static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b,
> @@ -1174,6 +1175,9 @@ static int nfs_compare_super(struct super_block *sb, struct fs_context *fc)
>  		return 0;
>  	if (!nfs_compare_userns(old, server))
>  		return 0;
> +	if ((old->has_sec_mnt_opts || fc->security) &&
> +			security_sb_mnt_opts_compat(sb, fc->security))
> +		return 0;
>  	return nfs_compare_mount_options(sb, server, fc);
>  }
>  
> diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
> index 38e60ec742df..3f0acada5794 100644
> --- a/include/linux/nfs_fs_sb.h
> +++ b/include/linux/nfs_fs_sb.h
> @@ -254,6 +254,7 @@ struct nfs_server {
>  
>  	/* User namespace info */
>  	const struct cred	*cred;
> +	bool			has_sec_mnt_opts;
>  };
>  
>  /* Server capabilities */



More information about the Linux-security-module-archive mailing list