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 commitc4ed4243
("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> (cherry picked from commit56c19e89b3
)
This commit is contained in:
Родитель
08fb39051f
Коммит
2962f5a5dc
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче