Skip to content

Commit

Permalink
xfs: kill suid/sgid through the truncate path.
Browse files Browse the repository at this point in the history
XFS has failed to kill suid/sgid bits correctly when truncating
files of non-zero size since commit c4ed424 ("xfs: split
xfs_setattr") introduced in the 3.1 kernel. Fix it.

Fix it.

cc: stable kernel <stable@vger.kernel.org>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
  • Loading branch information
Dave Chinner authored and Ben Myers committed May 30, 2013
1 parent 74137ff commit 56c19e8
Showing 1 changed file with 32 additions and 15 deletions.
47 changes: 32 additions & 15 deletions fs/xfs/xfs_iops.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,28 @@ xfs_vn_getattr(
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
xfs_setattr_nonsize(
struct xfs_inode *ip,
Expand Down Expand Up @@ -606,18 +628,8 @@ xfs_setattr_nonsize(
/*
* Change file access modes.
*/
if (mask & ATTR_MODE) {
umode_t mode = iattr->ia_mode;

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;
}
if (mask & ATTR_MODE)
xfs_setattr_mode(tp, ip, iattr);

/*
* Change file access or modified times.
Expand Down Expand Up @@ -714,9 +726,8 @@ xfs_setattr_size(
return XFS_ERROR(error);

ASSERT(S_ISREG(ip->i_d.di_mode));
ASSERT((mask & (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
ATTR_MTIME_SET|ATTR_KILL_SUID|ATTR_KILL_SGID|
ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);
ASSERT((mask & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET|
ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0);

if (!(flags & XFS_ATTR_NOLOCK)) {
lock_flags |= XFS_IOLOCK_EXCL;
Expand Down Expand Up @@ -860,6 +871,12 @@ xfs_setattr_size(
xfs_inode_clear_eofblocks_tag(ip);
}

/*
* Change file access modes.
*/
if (mask & ATTR_MODE)
xfs_setattr_mode(tp, ip, iattr);

if (mask & ATTR_CTIME) {
inode->i_ctime = iattr->ia_ctime;
ip->i_d.di_ctime.t_sec = iattr->ia_ctime.tv_sec;
Expand Down

0 comments on commit 56c19e8

Please sign in to comment.