All of lore.kernel.org
 help / color / mirror / Atom feed
From: Miklos Szeredi <miklos@szeredi.hu>
To: Jeff Layton <jlayton@redhat.com>
Cc: linux-fsdevel <linux-fsdevel@vger.kernel.org>,
	open list <linux-kernel@vger.kernel.org>,
	Al Viro <viro@zeniv.linux.org.uk>
Subject: Re: FUSE: regression when clearing setuid bits on chown
Date: Tue, 6 Dec 2016 15:39:14 +0100	[thread overview]
Message-ID: <20161206143914.GG2622@veci.piliscsaba.szeredi.hu> (raw)
In-Reply-To: <1481026405.2573.10.camel@redhat.com>

On Tue, Dec 06, 2016 at 07:13:25AM -0500, Jeff Layton wrote:

> Should we be checking that the latest i_mode even has these bits before
> sending down the mode change?

Fixed, see updated patch below.

It also fixes a bug in the previous patch where in case of "-rwsrwSr-x" it would
clear the sgid bit without execute.

> 
> > > +			attr->ia_mode = inode->i_mode & ~(S_ISUID | S_ISGID);
> > +			attr->ia_valid |= ATTR_MODE;
> >  		}
> >  	}
> >  	if (!attr->ia_valid)
> 
> Yeah that is quite a bit simpler.
> 
> That said...if either ATTR_KILL flag is set, then we're going to end up
> clearing both bits in the new mode. I guess that's ok since we always
> want to clear them both, and we'll only have one set and not the other
> if one of the mode bits was set and not the other.
> 
> But...I'm starting to wonder if we really need two flags for this. Would
> be be better served with a single ATTR_KILL_SUID_SGID flag? I wonder if
> that would simplify some of the logic in the whole setuid clearing
> morass.

Yeah, that would be a nice little cleanup.

Thanks,
Miklos
---

From: Miklos Szeredi <mszeredi@redhat.com>
Subject: fuse: fix clearing suid, sgid for chown()

Basically, the pjdfstests set the ownership of a file to 06555, and then
chowns it (as root) to a new uid/gid. Prior to commit a09f99eddef4 ("fuse:
fix killing s[ug]id in setattr"), fuse would send down a setattr with both
the uid/gid change and a new mode.  Now, it just sends down the uid/gid
change.

Technically this is NOTABUG, since POSIX doesn't _require_ that we clear
these bits for a privileged process, but Linux (wisely) has done that and I
think we don't want to change that behavior here.

This is caused by the use of should_remove_suid(), which will always return
0 when the process has CAP_FSETID.

In fact we really don't need to be calling should_remove_suid() at all,
since we've already been indicated that we should remove the suid, we just
don't want to use a (very) stale mode for that.

This patch should fix the above as well as simplify the logic.

Reported-by: Jeff Layton <jlayton@redhat.com> 
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Fixes: a09f99eddef4 ("fuse: fix killing s[ug]id in setattr")
Cc: <stable@vger.kernel.org>
---
 fs/fuse/dir.c |    7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1739,8 +1739,6 @@ static int fuse_setattr(struct dentry *e
 		 * This should be done on write(), truncate() and chown().
 		 */
 		if (!fc->handle_killpriv) {
-			int kill;
-
 			/*
 			 * ia_mode calculation may have used stale i_mode.
 			 * Refresh and recalculate.
@@ -1750,12 +1748,11 @@ static int fuse_setattr(struct dentry *e
 				return ret;
 
 			attr->ia_mode = inode->i_mode;
-			kill = should_remove_suid(entry);
-			if (kill & ATTR_KILL_SUID) {
+			if (inode->i_mode & S_ISUID) {
 				attr->ia_valid |= ATTR_MODE;
 				attr->ia_mode &= ~S_ISUID;
 			}
-			if (kill & ATTR_KILL_SGID) {
+			if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
 				attr->ia_valid |= ATTR_MODE;
 				attr->ia_mode &= ~S_ISGID;
 			}

  reply	other threads:[~2016-12-06 14:40 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-05 18:21 FUSE: regression when clearing setuid bits on chown Jeff Layton
2016-12-06 10:02 ` Miklos Szeredi
2016-12-06 12:13   ` Jeff Layton
2016-12-06 14:39     ` Miklos Szeredi [this message]
2016-12-06 14:45       ` Jeff Layton
2016-12-06 14:51         ` Miklos Szeredi
2016-12-06 14:54           ` Jeff Layton

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=20161206143914.GG2622@veci.piliscsaba.szeredi.hu \
    --to=miklos@szeredi.hu \
    --cc=jlayton@redhat.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --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.