Commit 2962f5a5 authored by Dave Chinner's avatar Dave Chinner Committed by Ben Myers

xfs: kill suid/sgid through the truncate path.

XFS has failed to kill suid/sgid bits correctly when truncating
files of non-zero size since commit c4ed4243 ("xfs: split
xfs_setattr") introduced in the 3.1 kernel. Fix it.

Fix it.

cc: stable kernel <stable@vger.kernel.org>
Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Signed-off-by: default avatarBen Myers <bpm@sgi.com>

(cherry picked from commit 56c19e89)
parent 08fb3905
...@@ -455,6 +455,28 @@ xfs_vn_getattr( ...@@ -455,6 +455,28 @@ xfs_vn_getattr(
return 0; return 0;
} }
static void
xfs_setattr_mode(
struct xfs_trans *tp,
struct xfs_inode *ip,
struct iattr *iattr)
{
struct inode *inode = VFS_I(ip);
umode_t mode = iattr->ia_mode;
ASSERT(tp);
ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
mode &= ~S_ISGID;
ip->i_d.di_mode &= S_IFMT;
ip->i_d.di_mode |= mode & ~S_IFMT;
inode->i_mode &= S_IFMT;
inode->i_mode |= mode & ~S_IFMT;
}
int int
xfs_setattr_nonsize( xfs_setattr_nonsize(
struct xfs_inode *ip, struct xfs_inode *ip,
...@@ -606,18 +628,8 @@ xfs_setattr_nonsize( ...@@ -606,18 +628,8 @@ xfs_setattr_nonsize(
/* /*
* Change file access modes. * Change file access modes.
*/ */
if (mask & ATTR_MODE) { if (mask & ATTR_MODE)
umode_t mode = iattr->ia_mode; xfs_setattr_mode(tp, ip, iattr);
if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
mode &= ~S_ISGID;
ip->i_d.di_mode &= S_IFMT;
ip->i_d.di_mode |= mode & ~S_IFMT;
inode->i_mode &= S_IFMT;
inode->i_mode |= mode & ~S_IFMT;
}
/* /*
* Change file access or modified times. * Change file access or modified times.
...@@ -714,9 +726,8 @@ xfs_setattr_size( ...@@ -714,9 +726,8 @@ xfs_setattr_size(
return XFS_ERROR(error); return XFS_ERROR(error);
ASSERT(S_ISREG(ip->i_d.di_mode)); ASSERT(S_ISREG(ip->i_d.di_mode));
ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID| ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
if (!(flags & XFS_ATTR_NOLOCK)) { if (!(flags & XFS_ATTR_NOLOCK)) {
lock_flags |= XFS_IOLOCK_EXCL; lock_flags |= XFS_IOLOCK_EXCL;
...@@ -860,6 +871,12 @@ xfs_setattr_size( ...@@ -860,6 +871,12 @@ xfs_setattr_size(
xfs_inode_clear_eofblocks_tag(ip); xfs_inode_clear_eofblocks_tag(ip);
} }
/*
* Change file access modes.
*/
if (mask & ATTR_MODE)
xfs_setattr_mode(tp, ip, iattr);
if (mask & ATTR_CTIME) { if (mask & ATTR_CTIME) {
inode->i_ctime = iattr->ia_ctime; inode->i_ctime = iattr->ia_ctime;
ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec; ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment