[PATCH] freevxfs: clamp i_size of immed inodes to the immediate area
From: Lin Jiapeng
Date: Mon Aug 03 2026 - 07:54:25 EST
For immed inodes (VXFS_ORG_IMMED) all file data is stored directly in
the VXFS_NIMMED (96) byte immediate area of the inode itself, so the
on-disk vdi_size of such an inode can never legitimately exceed that.
dip2vip_cpy(), however, copies vdi_size into inode->i_size without
checking it against the organisation type.
vxfs_immed_read_folio() uses folio_pos(folio) as an offset into the
96-byte vi_immed[] array and copies a whole page from there into the
page cache. With an i_size larger than VXFS_NIMMED, reading an immed
regular file -- or iterating an immed directory, which walks pages up
to i_size -- drives the copy past the end of the vxfs_inode_info
object, so unintended kernel memory is read and returned as file
contents.
The immed symlink path already guards against this by terminating the
link target within the immediate area (nd_terminate_link()); regular
files and directories have no equivalent check.
Clamp vii_size to VXFS_NIMMED for immed inodes when the on-disk inode
is read in, mirroring the existing symlink-side handling and keeping
vxfs_immed_read_folio() from ever indexing past the immediate area.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@xxxxxxxxxxxxxxx
Reported-by: TencentOS Corvus AI <corvus@xxxxxxxxxxx>
Signed-off-by: Lin Jiapeng <jiapenglin@xxxxxxxxxxx>
---
fs/freevxfs/vxfs_inode.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index 21fc94b9820..f0589b6c834 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -107,6 +107,14 @@ static inline void dip2vip_cpy(struct vxfs_sb_info *sbi,
i_gid_write(inode, (gid_t)vip->vii_gid);
set_nlink(inode, vip->vii_nlink);
+
+ /*
+ * For immed inodes all data lives in the VXFS_NIMMED-byte
+ * immediate area of the inode itself, so a larger on-disk size
+ * is bogus and must not be trusted.
+ */
+ if (VXFS_ISIMMED(vip) && vip->vii_size > VXFS_NIMMED)
+ vip->vii_size = VXFS_NIMMED;
inode->i_size = vip->vii_size;
inode_set_atime(inode, vip->vii_atime, 0);
--
2.50.1 (Apple Git-155)