All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Smalley <sds@tycho.nsa.gov>
To: Scott Mayhew <smayhew@redhat.com>,
	selinux@tycho.nsa.gov, linux-nfs@vger.kernel.org
Cc: Paul Moore <paul@paul-moore.com>,
	Eric Paris <eparis@parisplace.org>,
	Trond Myklebust <trondmy@primarydata.com>,
	"J . Bruce Fields" <bfields@fieldses.org>
Subject: Re: [PATCH] security/selinux: allow security_sb_clone_mnt_opts to enable/disable native labeling behavior
Date: Thu, 01 Jun 2017 14:30:07 -0400	[thread overview]
Message-ID: <1496341807.27759.15.camel@tycho.nsa.gov> (raw)
In-Reply-To: <20170601144628.26535-1-smayhew@redhat.com>

On Thu, 2017-06-01 at 10:46 -0400, Scott Mayhew wrote:
> When an NFSv4 client performs a mount operation, it first mounts the
> NFSv4 root and then does path walk to the exported path and performs
> a
> submount on that, cloning the security mount options from the root's
> superblock to the submount's superblock in the process.
> 
> Unless the NFS server has an explicit fsid=0 export with the
> "security_label" option, the NFSv4 root superblock will not have
> SBLABEL_MNT set, and neither will the submount superblock after
> cloning
> the security mount options.  As a result, setxattr's of security
> labels
> over NFSv4.2 will fail.  In a similar fashion, NFSv4.2 mounts mounted
> with the context= mount option will not show the correct labels
> because
> the nfs_server->caps flags of the cloned superblock will still have
> NFS_CAP_SECURITY_LABEL set.
> 
> Allowing the NFSv4 client to enable or disable
> SECURITY_LSM_NATIVE_LABELS
> behavior will ensure that the SBLABEL_MNT flag has the correct value
> when the client traverses from an exported path without the
> "security_label" option to one with the "security_label" option and
> vice versa.  Similarly, checking to see if SECURITY_LSM_NATIVE_LABELS
> is
> set upon return from security_sb_clone_mnt_opts() and clearing
> NFS_CAP_SECURITY_LABEL if necessary will allow the correct labels to
> be displayed for NFSv4.2 mounts mounted with the context= mount
> option.
> 
> Signed-off-by: Scott Mayhew <smayhew@redhat.com>
> ---
>  fs/nfs/super.c            | 18 +++++++++++++++++-
>  include/linux/lsm_hooks.h |  4 +++-
>  include/linux/security.h  |  8 ++++++--
>  security/security.c       |  7 +++++--
>  security/selinux/hooks.c  | 43
> ++++++++++++++++++++++++++++++++++++++-----
>  5 files changed, 69 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/nfs/super.c b/fs/nfs/super.c
> index 2f3822a..6a11535 100644
> --- a/fs/nfs/super.c
> +++ b/fs/nfs/super.c
> @@ -2544,10 +2544,26 @@ EXPORT_SYMBOL_GPL(nfs_set_sb_security);
>  int nfs_clone_sb_security(struct super_block *s, struct dentry
> *mntroot,
>  			  struct nfs_mount_info *mount_info)
>  {
> +	int error;
> +	unsigned long kflags = 0, kflags_out = 0;
> +
>  	/* clone any lsm security options from the parent to the new
> sb */
>  	if (d_inode(mntroot)->i_op != NFS_SB(s)->nfs_client-
> >rpc_ops->dir_inode_ops)
>  		return -ESTALE;
> -	return security_sb_clone_mnt_opts(mount_info->cloned->sb,
> s);
> +
> +	if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
> +		kflags |= SECURITY_LSM_NATIVE_LABELS;
> +
> +	error = security_sb_clone_mnt_opts(mount_info->cloned->sb,
> s, kflags, &kflags_out);
> +	if (error)
> +		goto err;

Not sure this is justified; coding style says to just return directly
if no cleanup is required.

> +
> +	if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL &&
> +		!(kflags_out & SECURITY_LSM_NATIVE_LABELS))
> +		NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL;
> +err:
> +	return error;
> +
>  }
>  EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
>  
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index 080f34e..2f54bfb 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -1388,7 +1388,9 @@ union security_list_options {
>  				unsigned long kern_flags,
>  				unsigned long *set_kern_flags);
>  	int (*sb_clone_mnt_opts)(const struct super_block *oldsb,
> -					struct super_block *newsb);
> +					struct super_block *newsb,
> +					unsigned long kern_flags,
> +					unsigned long
> *set_kern_flags);
>  	int (*sb_parse_opts_str)(char *options, struct
> security_mnt_opts *opts);
>  	int (*dentry_init_security)(struct dentry *dentry, int mode,
>  					const struct qstr *name,
> void **ctx,
> diff --git a/include/linux/security.h b/include/linux/security.h
> index af675b5..a55ae9c 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -240,7 +240,9 @@ int security_sb_set_mnt_opts(struct super_block
> *sb,
>  				unsigned long kern_flags,
>  				unsigned long *set_kern_flags);
>  int security_sb_clone_mnt_opts(const struct super_block *oldsb,
> -				struct super_block *newsb);
> +				struct super_block *newsb,
> +				unsigned long kern_flags,
> +				unsigned long *set_kern_flags);
>  int security_sb_parse_opts_str(char *options, struct
> security_mnt_opts *opts);
>  int security_dentry_init_security(struct dentry *dentry, int mode,
>  					const struct qstr *name,
> void **ctx,
> @@ -581,7 +583,9 @@ static inline int security_sb_set_mnt_opts(struct
> super_block *sb,
>  }
>  
>  static inline int security_sb_clone_mnt_opts(const struct
> super_block *oldsb,
> -					      struct super_block
> *newsb)
> +					      struct super_block
> *newsb,
> +					      unsigned long
> kern_flags,
> +					      unsigned long
> *set_kern_flags)
>  {
>  	return 0;
>  }
> diff --git a/security/security.c b/security/security.c
> index b9fea39..7b70ea2 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -380,9 +380,12 @@ int security_sb_set_mnt_opts(struct super_block
> *sb,
>  EXPORT_SYMBOL(security_sb_set_mnt_opts);
>  
>  int security_sb_clone_mnt_opts(const struct super_block *oldsb,
> -				struct super_block *newsb)
> +				struct super_block *newsb,
> +				unsigned long kern_flags,
> +				unsigned long *set_kern_flags)
>  {
> -	return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb);
> +	return call_int_hook(sb_clone_mnt_opts, 0, oldsb, newsb,
> +				kern_flags, set_kern_flags);
>  }
>  EXPORT_SYMBOL(security_sb_clone_mnt_opts);
>  
> diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
> index e67a526..80d9acf 100644
> --- a/security/selinux/hooks.c
> +++ b/security/selinux/hooks.c
> @@ -529,8 +529,14 @@ static int sb_finish_set_opts(struct super_block
> *sb)
>  		       sb->s_id, sb->s_type->name);
>  
>  	sbsec->flags |= SE_SBINITIALIZED;
> +
> +	/* Explicitly set or clear SBLABEL_MNT.  It's not sufficient
> to simply
> +	   leave the flag untouched because sb_clone_mnt_opts might
> be handing
> +	   us a superblock that needs the flag to be cleared. */

Coding style (and checkpatch.pl) prefer a different style for multi-
line comments.

>  	if (selinux_is_sblabel_mnt(sb))
>  		sbsec->flags |= SBLABEL_MNT;
> +	else
> +		sbsec->flags &= ~SBLABEL_MNT;
>  
>  	/* Initialize the root inode. */
>  	rc = inode_doinit_with_dentry(root_inode, root);
> @@ -963,8 +969,11 @@ static int selinux_cmp_sb_context(const struct
> super_block *oldsb,
>  }
>  
>  static int selinux_sb_clone_mnt_opts(const struct super_block
> *oldsb,
> -					struct super_block *newsb)
> +					struct super_block *newsb,
> +					unsigned long kern_flags,
> +					unsigned long
> *set_kern_flags)
>  {
> +	int rc = 0;
>  	const struct superblock_security_struct *oldsbsec = oldsb-
> >s_security;
>  	struct superblock_security_struct *newsbsec = newsb-
> >s_security;
>  
> @@ -977,14 +986,23 @@ static int selinux_sb_clone_mnt_opts(const
> struct super_block *oldsb,
>  	 * mount options.  thus we can safely deal with this
> superblock later
>  	 */
>  	if (!ss_initialized)
> -		return 0;
> +		goto out;

Likewise, don't see the point of this since no cleanup is required, and
as per coding style.

> +
> +	if (kern_flags && !set_kern_flags) {
> +		/* Specifying internal flags without providing a
> place to
> +		 * place the results is not allowed */
> +		rc = -EINVAL;
> +		goto out;

Ditto, just return directly.

> +	}
>  
>  	/* how can we clone if the old one wasn't set up?? */
>  	BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
>  
>  	/* if fs is reusing a sb, make sure that the contexts match
> */
> -	if (newsbsec->flags & SE_SBINITIALIZED)
> -		return selinux_cmp_sb_context(oldsb, newsb);
> +	if (newsbsec->flags & SE_SBINITIALIZED) {
> +		rc = selinux_cmp_sb_context(oldsb, newsb);
> +		goto out;
> +	}

And again.

>  
>  	mutex_lock(&newsbsec->lock);
>  
> @@ -994,6 +1012,19 @@ static int selinux_sb_clone_mnt_opts(const
> struct super_block *oldsb,
>  	newsbsec->def_sid = oldsbsec->def_sid;
>  	newsbsec->behavior = oldsbsec->behavior;
>  
> +	if (newsbsec->behavior == SECURITY_FS_USE_NATIVE
> +			&& !(kern_flags &
> SECURITY_LSM_NATIVE_LABELS)
> +			&& !set_context) {

I prefer ending the prior line with &&, not beginning the next one with
it. Also indentation of the continuation lines seems excessive.

> +		rc = security_fs_use(newsb);
> +		if (rc)
> +			goto out_unlock;
> +	}
> +
> +	if (kern_flags & SECURITY_LSM_NATIVE_LABELS && !set_context)
> {
> +		newsbsec->behavior = SECURITY_FS_USE_NATIVE;
> +		*set_kern_flags |= SECURITY_LSM_NATIVE_LABELS;
> +	}
> +
>  	if (set_context) {
>  		u32 sid = oldsbsec->mntpoint_sid;
>  
> @@ -1013,8 +1044,10 @@ static int selinux_sb_clone_mnt_opts(const
> struct super_block *oldsb,
>  	}
>  
>  	sb_finish_set_opts(newsb);
> +out_unlock:
>  	mutex_unlock(&newsbsec->lock);
> -	return 0;
> +out:
> +	return rc;
>  }
>  
>  static int selinux_parse_opts_str(char *options,

  parent reply	other threads:[~2017-06-01 18:30 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-29 15:27 [PATCH] selinux: Fix SBLABEL_MNT for NFS mounts Tomeu Vizoso
2017-03-29 15:27 ` Tomeu Vizoso
2017-03-29 21:34 ` J. Bruce Fields
2017-03-29 21:34   ` J. Bruce Fields
2017-03-30  7:49   ` Tomeu Vizoso
2017-03-30  7:49     ` Tomeu Vizoso
2017-03-30 17:27     ` Stephen Smalley
2017-03-30 17:27       ` Stephen Smalley
2017-03-30 17:41       ` J. Bruce Fields
2017-03-30 17:41         ` J. Bruce Fields
2017-03-30 17:52         ` Stephen Smalley
2017-03-30 17:52           ` Stephen Smalley
2017-04-04 23:26           ` J. Bruce Fields
2017-04-04 23:26             ` J. Bruce Fields
2017-05-25 21:07             ` [PATCH RFC 0/2] Fix setting of security labels over NFSv4.2 Scott Mayhew
2017-05-25 21:07               ` [PATCH RFC 1/2] selinux: allow SECURITY_LSM_NATIVE_LABELS to be set on an already initialized superblock Scott Mayhew
2017-05-25 21:07               ` [PATCH RFC 2/2] nfs: update labeling behavior on a superblock when submounting Scott Mayhew
2017-05-26 14:24                 ` Stephen Smalley
2017-05-26 15:28                   ` Scott Mayhew
2017-05-26 15:42                     ` Stephen Smalley
2017-06-01 14:46                       ` [PATCH] security/selinux: allow security_sb_clone_mnt_opts to enable/disable native labeling behavior Scott Mayhew
2017-06-01 14:55                         ` Scott Mayhew
2017-06-01 18:08                           ` Stephen Smalley
2017-06-01 18:48                             ` Stephen Smalley
2017-06-01 19:40                             ` Scott Mayhew
2017-06-01 18:30                         ` Stephen Smalley [this message]
2017-06-01 19:42                           ` Scott Mayhew
2017-06-01 20:59                           ` [PATCH v2] " Scott Mayhew
2017-06-02 12:55                             ` Stephen Smalley
2017-06-02 13:09                               ` Scott Mayhew
2017-06-05 15:45                                 ` [PATCH v3] " Scott Mayhew
2017-06-05 15:55                                   ` Scott Mayhew
2017-06-05 19:53                                   ` Stephen Smalley
2017-06-05 21:21                                   ` Paul Moore
2017-06-06  0:46                                     ` J . Bruce Fields
2017-06-09 20:24                                       ` Paul Moore
2017-05-30 14:38                     ` [PATCH RFC 2/2] nfs: update labeling behavior on a superblock when submounting Stephen Smalley
2017-05-30 19:40                       ` J . Bruce Fields
2017-05-30 19:52                         ` Stephen Smalley
2017-05-26 14:48               ` [PATCH RFC 0/2] Fix setting of security labels over NFSv4.2 Stephen Smalley
2017-05-26 15:17                 ` J . Bruce Fields
2017-05-26 15:18                   ` J . Bruce Fields
2017-05-26 15:30                 ` Scott Mayhew

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1496341807.27759.15.camel@tycho.nsa.gov \
    --to=sds@tycho.nsa.gov \
    --cc=bfields@fieldses.org \
    --cc=eparis@parisplace.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=paul@paul-moore.com \
    --cc=selinux@tycho.nsa.gov \
    --cc=smayhew@redhat.com \
    --cc=trondmy@primarydata.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.