[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