Skip to content

Commit 5aa5b27

Browse files
author
Darrick J. Wong
committed
xfs: don't expose misaligned extszinherit hints to userspace
Commit 603f000 changed xfs_ioctl_setattr_check_extsize to reject an attempt to set an EXTSZINHERIT extent size hint on a directory with RTINHERIT set if the hint isn't a multiple of the realtime extent size. However, I have recently discovered that it is possible to change the realtime extent size when adding a rt device to a filesystem, which means that the existence of directories with misaligned inherited hints is not an accident. As a result, it's possible that someone could have set a valid hint and added an rt volume with a different rt extent size, which invalidates the ondisk hints. After such a sequence, FSGETXATTR will report a misaligned hint, which FSSETXATTR will trip over, causing confusion if the user was doing the usual GET/SET sequence to change some other attribute. Change xfs_fill_fsxattr to omit the hint if it isn't aligned properly. Fixes: 603f000 ("xfs: validate extsz hints against rt extent size when rtinherit is set") Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent 83193e5 commit 5aa5b27

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

fs/xfs/xfs_ioctl.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,24 @@ xfs_fill_fsxattr(
10651065

10661066
fileattr_fill_xflags(fa, xfs_ip2xflags(ip));
10671067

1068-
fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
1068+
if (ip->i_diflags & XFS_DIFLAG_EXTSIZE) {
1069+
fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
1070+
} else if (ip->i_diflags & XFS_DIFLAG_EXTSZINHERIT) {
1071+
/*
1072+
* Don't let a misaligned extent size hint on a directory
1073+
* escape to userspace if it won't pass the setattr checks
1074+
* later.
1075+
*/
1076+
if ((ip->i_diflags & XFS_DIFLAG_RTINHERIT) &&
1077+
ip->i_extsize % mp->m_sb.sb_rextsize > 0) {
1078+
fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE |
1079+
FS_XFLAG_EXTSZINHERIT);
1080+
fa->fsx_extsize = 0;
1081+
} else {
1082+
fa->fsx_extsize = XFS_FSB_TO_B(mp, ip->i_extsize);
1083+
}
1084+
}
1085+
10691086
if (ip->i_diflags2 & XFS_DIFLAG2_COWEXTSIZE)
10701087
fa->fsx_cowextsize = XFS_FSB_TO_B(mp, ip->i_cowextsize);
10711088
fa->fsx_projid = ip->i_projid;

0 commit comments

Comments
 (0)