linux-unionfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Eryu Guan <guaneryu@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: linux-unionfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH] ovl: fix sgid inhertance over whiteout
Date: Fri, 26 Aug 2016 18:48:16 +0800	[thread overview]
Message-ID: <20160826104816.GB2462@eguan.usersys.redhat.com> (raw)
In-Reply-To: <20160826095049.GJ25404@veci.piliscsaba.szeredi.hu>

On Fri, Aug 26, 2016 at 11:50:49AM +0200, Miklos Szeredi wrote:
> On Thu, Aug 25, 2016 at 04:15:02PM +0800, Eryu Guan wrote:
> > In commit bb0d2b8ad296 ("ovl: fix sgid on directory"), mode of newly
> > created files & dirs over whiteout was updated to pickup sgid bit. But
> > it used stat->mode directly, which could not be the correct mode,
> > because stat->mode could be tailored against umask.
> > 
> > This can be demonstrated by the following script:
> > 
> > umask 022
> > mkdir -p lower/dir upper work mnt
> > chown test:test lower/dir
> > chmod 2775 lower/dir
> > touch lower/dir/testdir
> > touch lower/dir/testfile
> > 
> > mount -t overlay -olowerdir=lower,upperdir=upper,workdir=work none mnt
> > rm -f mnt/dir/testdir
> > mkdir mnt/dir/testdir
> > rm -f mnt/dir/testfile
> > touch mnt/dir/testfile
> > touch mnt/dir/newfile
> > ls -l mnt/dir
> > 
> > -rw-r--r--. 1 root test 0 Aug 25 15:45 newfile
> > drwxrwsrwx. 2 root test 6 Aug 25 15:45 testdir
> > -rw-rw-rw-. 1 root test 0 Aug 25 15:45 testfile
> > 
> > testdir and testfile are created over whiteout, the modes contain write
> > permission for group and other, but they shouldn't, like 'newfile'.
> 
> Hi Eryu,
> 
> Yeah, the reson is that we fail to take umask into account.  And that's due to
> 
> +       sb->s_flags |= MS_POSIXACL;
> 
> in 39a25b2b3762 ("ovl: define ->get_acl() for overlay inodes").
> 
> Your patch works around this by relying on the mode of the file created in
> workdir, but this only solves part of the problem, and is also not very clean,
> since inode_init_owner() should only be called inode of the filesystem itself,
> not for foreign inodes.
> 
> The below patch should fix this together with the default posix acl inheritance,
> which also has an effect on mode of created inode.

I tested this patch and it passed my test case.

> 
> It would be nice to get complete test coverage for file creation which is quite
> complicated and apparently bug prone.  Variables to test for:

Thanks, I'll look into them and try to generate test cases for fstests.
Some cases have been covered by existing cases, I'll focus on create
over whiteout.

Thanks,
Eryu

> 
> 1) create over whiteout or not
> 
>    - behavior shouldn't change but different codepaths are taken
> 
> 2) creating directory, nodirectory, symlink or hard link
> 
>    - hard link: no new inode is created, attributes, ACL, etc. of old inode are
>      not changed
> 
>    - symlink has fix mode
> 
>    - if neither sgid or default ACL on parent then create mode calculated based
>      on supplied mode and umask
> 
>    - otherwise see below
> 
> 3) parent has sgid or not
> 
>    - if sgid is set AND creating directory then inherit sgid
> 
>    - if sgid is set then inherit group
> 
> 4) parent has default ACL or not
> 
>    - if parent has default ACL and creating a directory then inherit default ACL
> 
>    - if parent has default ACL then set mode and access ACL based on default ACL
>      of parent
> 
> 5) underlying filsystem sets MS_POSIXACL or not
> 
>    - codepaths might differ; shouldn't change behavior
> 
>    - unfrortunately I don't think there's a filesystem that supports overlayfs
>      upperdir but not POSIX ACL, so this needs separate kernel configs to test.
> 
> So that's quite a few independent parameters, resulting in lots of cases.  I
> guess it's easier to write a generic test case which can test all combinations
> above, than to write individual test cases by hand.
> 
> Thanks,
> Miklos
> ----
> 
> From: Miklos Szeredi <mszeredi@redhat.com>
> Subject: ovl: handle umask and posix_acl_default correctly on creation
> 
> Setting MS_POSIXACL in sb->s_flags has the side effect of passing mode to
> create functions without masking against umask.
> 
> Another problem when creating over a whiteout is that the default posix acl
> is not inherited from the parent dir (because the real parent dir at the
> time of creation is the work directory).
> 
> Fix these problems by:
> 
>  a) If upper fs does not have MS_POSIXACL, then mask mode with umask.
> 
>  b) If creating over a whiteout, call posix_acl_create() to get the
>  inherited acls.  After creation (but before moving to the final
>  destination) set these acls on the created file.  posix_acl_create() also
>  updates the file creation mode as appropriate.
> 
> Fixes: 39a25b2b3762 ("ovl: define ->get_acl() for overlay inodes")
> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> ---
>  fs/overlayfs/dir.c |   56 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 56 insertions(+)
> 
> --- a/fs/overlayfs/dir.c
> +++ b/fs/overlayfs/dir.c
> @@ -12,6 +12,8 @@
>  #include <linux/xattr.h>
>  #include <linux/security.h>
>  #include <linux/cred.h>
> +#include <linux/posix_acl.h>
> +#include <linux/posix_acl_xattr.h>
>  #include "overlayfs.h"
>  
>  void ovl_cleanup(struct inode *wdir, struct dentry *wdentry)
> @@ -186,6 +188,9 @@ static int ovl_create_upper(struct dentr
>  	struct dentry *newdentry;
>  	int err;
>  
> +	if (!hardlink && !IS_POSIXACL(udir))
> +		stat->mode &= ~current_umask();
> +
>  	inode_lock_nested(udir, I_MUTEX_PARENT);
>  	newdentry = lookup_one_len(dentry->d_name.name, upperdir,
>  				   dentry->d_name.len);
> @@ -335,6 +340,32 @@ static struct dentry *ovl_check_empty_an
>  	return ret;
>  }
>  
> +static int ovl_set_upper_acl(struct dentry *upperdentry, const char *name,
> +			     const struct posix_acl *acl)
> +{
> +	void *buffer;
> +	size_t size;
> +	int err;
> +
> +	if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !acl)
> +		return 0;
> +
> +	size = posix_acl_to_xattr(NULL, acl, NULL, 0);
> +	buffer = kmalloc(size, GFP_KERNEL);
> +	if (!buffer)
> +		return -ENOMEM;
> +
> +	size = posix_acl_to_xattr(&init_user_ns, acl, buffer, size);
> +	err = size;
> +	if (err < 0)
> +		goto out_free;
> +
> +	err = vfs_setxattr(upperdentry, name, buffer, size, XATTR_CREATE);
> +out_free:
> +	kfree(buffer);
> +	return err;
> +}
> +
>  static int ovl_create_over_whiteout(struct dentry *dentry, struct inode *inode,
>  				    struct kstat *stat, const char *link,
>  				    struct dentry *hardlink)
> @@ -346,10 +377,20 @@ static int ovl_create_over_whiteout(stru
>  	struct dentry *upper;
>  	struct dentry *newdentry;
>  	int err;
> +	struct posix_acl *acl, *default_acl;
>  
>  	if (WARN_ON(!workdir))
>  		return -EROFS;
>  
> +	if (!hardlink) {
> +		if (!IS_POSIXACL(udir))
> +			stat->mode &= ~current_umask();
> +
> +		err = posix_acl_create(udir, &stat->mode, &default_acl, &acl);
> +		if (err)
> +			return err;
> +	}
> +
>  	err = ovl_lock_rename_workdir(workdir, upperdir);
>  	if (err)
>  		goto out;
> @@ -384,6 +425,17 @@ static int ovl_create_over_whiteout(stru
>  		if (err)
>  			goto out_cleanup;
>  	}
> +	if (!hardlink) {
> +		err = ovl_set_upper_acl(newdentry, XATTR_NAME_POSIX_ACL_ACCESS,
> +					acl);
> +		if (err)
> +			goto out_cleanup;
> +
> +		err = ovl_set_upper_acl(newdentry, XATTR_NAME_POSIX_ACL_DEFAULT,
> +					default_acl);
> +		if (err)
> +			goto out_cleanup;
> +	}
>  
>  	if (!hardlink && S_ISDIR(stat->mode)) {
>  		err = ovl_set_opaque(newdentry);
> @@ -410,6 +462,10 @@ static int ovl_create_over_whiteout(stru
>  out_unlock:
>  	unlock_rename(workdir, upperdir);
>  out:
> +	if (!hardlink) {
> +		posix_acl_release(acl);
> +		posix_acl_release(default_acl);
> +	}
>  	return err;
>  
>  out_cleanup:
> 
> 

      reply	other threads:[~2016-08-26 10:48 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-25  8:15 [PATCH] ovl: fix sgid inhertance over whiteout Eryu Guan
2016-08-26  9:50 ` Miklos Szeredi
2016-08-26 10:48   ` Eryu Guan [this message]

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=20160826104816.GB2462@eguan.usersys.redhat.com \
    --to=guaneryu@gmail.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).