All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] xfs: fix signed calculation related to XFS_LITINO(mp)
@ 2020-11-12  6:30 Gao Xiang
  2020-11-12 15:53 ` Eric Sandeen
  2020-11-13  1:50 ` [PATCH v2] xfs: fix forkoff miscalculation " Gao Xiang
  0 siblings, 2 replies; 11+ messages in thread
From: Gao Xiang @ 2020-11-12  6:30 UTC (permalink / raw)
  To: linux-xfs
  Cc: Christoph Hellwig, Darrick J. Wong, Eric Sandeen, Gao Xiang, stable

Currently, commit e9e2eae89ddb dropped a (int) decoration from
XFS_LITINO(mp), and since sizeof() expression is also involved,
the result of XFS_LITINO(mp) is simply as the size_t type
(commonly unsigned long).

Considering the expression in xfs_attr_shortform_bytesfit():
  offset = (XFS_LITINO(mp) - bytes) >> 3;
let "bytes" be (int)340, and
    "XFS_LITINO(mp)" be (unsigned long)336.

on 64-bit platform, the expression is
  offset = ((unsigned long)336 - (int)340) >> 8 =
           (int)(0xfffffffffffffffcUL >> 3) = -1

but on 32-bit platform, the expression is
  offset = ((unsigned long)336 - (int)340) >> 8 =
           (int)(0xfffffffcUL >> 3) = 0x1fffffff
instead.

so offset becomes a large number on 32-bit platform, and cause
xfs_attr_shortform_bytesfit() returns maxforkoff rather than 0

Therefore, one result is
  "ASSERT(new_size <= XFS_IFORK_SIZE(ip, whichfork));"
  assertion failure in xfs_idata_realloc().

, which can be triggered with the following commands:
 touch a;
 setfattr -n user.0 -v "`seq 0 80`" a;
 setfattr -n user.1 -v "`seq 0 80`" a
on 32-bit platform.

Fix it by restoring (int) decorator to XFS_LITINO(mp) since
int type for XFS_LITINO(mp) is safe and all pre-exist signed
calculations are correct.

Fixes: e9e2eae89ddb ("xfs: only check the superblock version for dinode size calculation")
Cc: <stable@vger.kernel.org> # 5.7+
Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
---
I'm not sure this is the preferred way or just simply fix
xfs_attr_shortform_bytesfit() since I don't look into the
rest of XFS_LITINO(mp) users. Add (int) to XFS_LITINO(mp)
will avoid all potential regression at least.

 fs/xfs/libxfs/xfs_format.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index dd764da08f6f..f58f0a44c024 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -1061,7 +1061,7 @@ enum xfs_dinode_fmt {
 		sizeof(struct xfs_dinode) : \
 		offsetof(struct xfs_dinode, di_crc))
 #define XFS_LITINO(mp) \
-	((mp)->m_sb.sb_inodesize - XFS_DINODE_SIZE(&(mp)->m_sb))
+	((int)((mp)->m_sb.sb_inodesize - XFS_DINODE_SIZE(&(mp)->m_sb)))
 
 /*
  * Inode data & attribute fork sizes, per inode.
-- 
2.18.4


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-11-14 19:08 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-12  6:30 [PATCH] xfs: fix signed calculation related to XFS_LITINO(mp) Gao Xiang
2020-11-12 15:53 ` Eric Sandeen
2020-11-12 18:30   ` Darrick J. Wong
2020-11-13  2:04     ` Gao Xiang
2020-11-13  2:12       ` Gao Xiang
2020-11-13  1:50 ` [PATCH v2] xfs: fix forkoff miscalculation " Gao Xiang
2020-11-13 15:31   ` Dennis Gilmore
2020-11-14 10:32   ` Christoph Hellwig
2020-11-14 13:49     ` Gao Xiang
2020-11-14 14:02   ` [PATCH v3] " Gao Xiang
2020-11-14 19:06     ` Darrick J. Wong

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.