All of lore.kernel.org
 help / color / mirror / Atom feed
From: Casey Schaufler <casey@schaufler-ca.com>
To: Vivek Goyal <vgoyal@redhat.com>,
	miklos@szeredi.hu, sds@tycho.nsa.gov,
	linux-kernel@vger.kernel.org, linux-unionfs@vger.kernel.org,
	linux-security-module@vger.kernel.org
Cc: dwalsh@redhat.com, dhowells@redhat.com, pmoore@redhat.com,
	viro@ZenIV.linux.org.uk, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH 5/5] overlayfs: Use vfs_getxattr_noperm() for real inode
Date: Tue, 5 Jul 2016 13:29:39 -0700	[thread overview]
Message-ID: <b62a4ca9-3f75-b662-108b-1dec85c40ba1@schaufler-ca.com> (raw)
In-Reply-To: <1467733854-6314-6-git-send-email-vgoyal@redhat.com>

On 7/5/2016 8:50 AM, Vivek Goyal wrote:
> ovl_getxattr() currently uses vfs_getxattr() on realinode. This fails
> if mounter does not have DAC/MAC permission to access getxattr.
>
> Specifically this becomes a problem when selinux is trying to initialize
> overlay inode and does ->getxattr(overlay_inode). A task might trigger
> initialization of overlay inode and we will access real inode xattr in the
> context of mounter and if mounter does not have permissions, then inode
> selinux context initialization fails and inode is labeled as unlabeled_t.
>
> One way to deal with it is to let SELinux do getxattr checks both on
> overlay inode and underlying inode and overlay can call vfs_getxattr_noperm()
> to make sure when selinux is trying to initialize label on inode, it does
> not go through checks on lower levels and initialization is successful.
> And after inode initialization, SELinux will make sure task has getatttr
> permission.
>
> One issue with this approach is that it does not work for directories as
> d_real() returns the overlay dentry for directories and not the underlying
> directory dentry.
>
> Another way to deal with it to introduce another function pointer in
> inode_operations, say getxattr_noperm(), which is responsible to get
> xattr without any checks. SELinux initialization code will call this
> first if it is available on inode. So user space code path will call
> ->getxattr() and that will go through checks and SELinux internal
> initialization will call ->getxattr_noperm() and that will not
> go through checks.
>
> For now, I am just converting ovl_getxattr() to get xattr without
> any checks on underlying inode. That means it is possible for
> a task to get xattr of a file/dir on lower/upper through overlay mount
> while it is not possible outside overlay mount.
>
> If this is a major concern, I can look into implementing getxattr_noperm().

This is a major concern.

>
> Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
> ---
>  fs/overlayfs/inode.c  |  7 +------
>  fs/xattr.c            | 28 +++++++++++++++++++---------
>  include/linux/xattr.h |  1 +
>  3 files changed, 21 insertions(+), 15 deletions(-)
>
> diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
> index 36dfd86..a5d3320 100644
> --- a/fs/overlayfs/inode.c
> +++ b/fs/overlayfs/inode.c
> @@ -233,16 +233,11 @@ ssize_t ovl_getxattr(struct dentry *dentry, struct inode *inode,
>  		     const char *name, void *value, size_t size)
>  {
>  	struct dentry *realdentry = ovl_dentry_real(dentry);
> -	ssize_t sz;
> -	const struct cred *old_cred;
>  
>  	if (ovl_is_private_xattr(name))
>  		return -ENODATA;
>  
> -	old_cred = ovl_override_creds(dentry->d_sb);
> -	sz = vfs_getxattr(realdentry, name, value, size);
> -	revert_creds(old_cred);
> -	return size;
> +	return vfs_getxattr_noperm(realdentry, name, value, size);
>  }
>  
>  ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
> diff --git a/fs/xattr.c b/fs/xattr.c
> index 4beafc4..973e18c 100644
> --- a/fs/xattr.c
> +++ b/fs/xattr.c
> @@ -209,19 +209,11 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value,
>  }
>  
>  ssize_t
> -vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
> +vfs_getxattr_noperm(struct dentry *dentry, const char *name, void *value, size_t size)
>  {
>  	struct inode *inode = dentry->d_inode;
>  	int error;
>  
> -	error = xattr_permission(inode, name, MAY_READ);
> -	if (error)
> -		return error;
> -
> -	error = security_inode_getxattr(dentry, name);
> -	if (error)
> -		return error;
> -
>  	if (!strncmp(name, XATTR_SECURITY_PREFIX,
>  				XATTR_SECURITY_PREFIX_LEN)) {
>  		const char *suffix = name + XATTR_SECURITY_PREFIX_LEN;
> @@ -242,6 +234,24 @@ nolsm:
>  
>  	return error;
>  }
> +EXPORT_SYMBOL_GPL(vfs_getxattr_noperm);
> +
> +ssize_t
> +vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size)
> +{
> +	struct inode *inode = dentry->d_inode;
> +	int error;
> +
> +	error = xattr_permission(inode, name, MAY_READ);
> +	if (error)
> +		return error;
> +
> +	error = security_inode_getxattr(dentry, name);
> +	if (error)
> +		return error;
> +
> +	return vfs_getxattr_noperm(dentry, name, value, size);
> +}
>  EXPORT_SYMBOL_GPL(vfs_getxattr);
>  
>  ssize_t
> diff --git a/include/linux/xattr.h b/include/linux/xattr.h
> index 94079ba..832a6b6 100644
> --- a/include/linux/xattr.h
> +++ b/include/linux/xattr.h
> @@ -47,6 +47,7 @@ struct xattr {
>  
>  ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
>  ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t);
> +ssize_t vfs_getxattr_noperm(struct dentry *, const char *, void *, size_t);
>  ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
>  int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int);
>  int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);

  reply	other threads:[~2016-07-05 20:29 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-07-05 15:50 [PATCH 0/5][RFC] Overlayfs SELinux Support Vivek Goyal
2016-07-05 15:50 ` [PATCH 1/5] security, overlayfs: provide copy up security hook for unioned files Vivek Goyal
2016-07-05 16:53   ` kbuild test robot
2016-07-05 16:53     ` kbuild test robot
2016-07-05 17:43     ` Vivek Goyal
2016-07-05 17:20   ` kbuild test robot
2016-07-05 17:20     ` kbuild test robot
2016-07-05 19:36   ` Casey Schaufler
2016-07-05 20:42     ` Vivek Goyal
2016-07-07 20:33     ` Vivek Goyal
2016-07-07 21:44       ` Casey Schaufler
2016-07-08  7:21         ` Miklos Szeredi
2016-07-08 12:45           ` Vivek Goyal
2016-07-08 13:42             ` Vivek Goyal
2016-07-08 15:34               ` Casey Schaufler
2016-07-05 21:35   ` Paul Moore
2016-07-05 21:52     ` Vivek Goyal
2016-07-05 22:03       ` Paul Moore
2016-07-05 15:50 ` [PATCH 2/5] security,overlayfs: Provide security hook for copy up of xattrs for overlay file Vivek Goyal
2016-07-05 20:22   ` Casey Schaufler
2016-07-05 21:15     ` Vivek Goyal
2016-07-05 21:34       ` Casey Schaufler
2016-07-06 17:09         ` Vivek Goyal
2016-07-06 17:50           ` Vivek Goyal
2016-07-06 19:01           ` Vivek Goyal
2016-07-06 19:22             ` Casey Schaufler
2016-07-05 21:45   ` Paul Moore
2016-07-05 21:53     ` Vivek Goyal
2016-07-05 15:50 ` [PATCH 3/5] selinux: Pass security pointer to determine_inode_label() Vivek Goyal
2016-07-05 20:25   ` Casey Schaufler
2016-07-05 21:09     ` Vivek Goyal
2016-07-05 15:50 ` [PATCH 4/5] overlayfs: Correctly label newly created file over whiteout Vivek Goyal
2016-07-05 15:50 ` [PATCH 5/5] overlayfs: Use vfs_getxattr_noperm() for real inode Vivek Goyal
2016-07-05 20:29   ` Casey Schaufler [this message]
2016-07-05 21:16     ` Vivek Goyal
2016-07-06  4:36       ` Miklos Szeredi
2016-07-06 10:54         ` Vivek Goyal
2016-07-06 14:58           ` Miklos Szeredi
2016-07-07 18:35             ` Vivek Goyal
2016-07-08  7:06               ` Miklos Szeredi
2016-07-08 15:28                 ` Casey Schaufler

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=b62a4ca9-3f75-b662-108b-1dec85c40ba1@schaufler-ca.com \
    --to=casey@schaufler-ca.com \
    --cc=dhowells@redhat.com \
    --cc=dwalsh@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=pmoore@redhat.com \
    --cc=sds@tycho.nsa.gov \
    --cc=vgoyal@redhat.com \
    --cc=viro@ZenIV.linux.org.uk \
    /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.