suid and sgid should be cleared when unprivileged user writes to such
files. Overlayfs fails to do so because of the ovl level inode has no
S_ISUID or S_ISGID set and should_remove_suid() fails to set
ATTR_KILL_[SG]ID. xfstests generic/193 reveals the failure on overlayfs.

echo test > /mnt/overlay/testfile
chmod a+s /mnt/overlay/testfile
chown test:test /mnt/overlay/testfile
su test -c "echo > /mnt/overlay/testfile"

The suid bit should be cleard after being written by test user.

Fix it by updating attr on ovl level inode in ovl_setattr(), so the attr
is consistent with inode in upper level.

Signed-off-by: Eryu Guan <guane...@gmail.com>
---
 fs/overlayfs/inode.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 4060ffd..dbe0815 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -50,11 +50,22 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
        if (!err) {
                upperdentry = ovl_dentry_upper(dentry);
 
+               /*
+                * notify_change() assumes ATTR_KILL_[SG]ID and ATTR_MODE are
+                * not set at the same time. Clear ATTR_MODE before we call the
+                * next notify_change().
+                */
+               if ((attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) &&
+                   (attr->ia_valid & ATTR_MODE))
+                       attr->ia_valid &= ~ATTR_MODE;
                mutex_lock(&upperdentry->d_inode->i_mutex);
                err = notify_change(upperdentry, attr, NULL);
                mutex_unlock(&upperdentry->d_inode->i_mutex);
        }
        ovl_drop_write(dentry);
+       /* Also update the inode in ovl level, for consistency. */
+       if (!err)
+               setattr_copy(d_inode(dentry), attr);
 out:
        return err;
 }
-- 
1.8.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-unionfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to