[PATCH] freevxfs: validate OLT record sizes
From: Samuel Moelius
Date: Mon Jun 08 2026 - 20:51:25 EST
vxfs_read_olt() walks the Object Location Table by adding each on-disk
record's olt_size to the current pointer. A malformed filesystem can set
an OLT record size to zero, leaving the pointer unchanged and spinning
the mount task in the OLT parser.
Reject invalid OLT header sizes and reject records smaller than the
common record header or larger than the remaining OLT extent before
advancing.
Assisted-by: Codex:gpt-5.5-cyber-preview
Signed-off-by: Samuel Moelius <sam.moelius@xxxxxxxxxxxxxxx>
---
fs/freevxfs/vxfs_olt.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
index 23f35187c289..81de018bc462 100644
--- a/fs/freevxfs/vxfs_olt.c
+++ b/fs/freevxfs/vxfs_olt.c
@@ -77,12 +77,22 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
goto fail;
}
- oaddr = bp->b_data + fs32_to_cpu(infp, op->olt_size);
eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
+ oaddr = bp->b_data + fs32_to_cpu(infp, op->olt_size);
+ if (oaddr < bp->b_data + sizeof(*op) || oaddr > eaddr) {
+ pr_notice("vxfs: invalid olt header size\n");
+ goto fail;
+ }
while (oaddr < eaddr) {
struct vxfs_oltcommon *ocp =
(struct vxfs_oltcommon *)oaddr;
+ u32 size = fs32_to_cpu(infp, ocp->olt_size);
+
+ if (size < sizeof(*ocp) || size > eaddr - oaddr) {
+ pr_notice("vxfs: invalid olt record size\n");
+ goto fail;
+ }
switch (fs32_to_cpu(infp, ocp->olt_type)) {
case VXFS_OLT_FSHEAD:
@@ -93,7 +103,7 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize)
break;
}
- oaddr += fs32_to_cpu(infp, ocp->olt_size);
+ oaddr += size;
}
brelse(bp);
--
2.43.0