mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] freevxfs: reject invalid OLT record sizes
@ 2026-07-22 10:57 Sangho Lee
  2026-07-22 12:10 ` Christoph Hellwig
  0 siblings, 1 reply; 3+ messages in thread
From: Sangho Lee @ 2026-07-22 10:57 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-kernel, Sangho Lee, stable

vxfs_read_olt() walks image-controlled Object Location Table records by
adding each record's on-disk olt_size to the current cursor:

	oaddr += fs32_to_cpu(infp, ocp->olt_size);

The value is not checked before it is used. A crafted VxFS image can set a
record size to zero, which prevents the cursor from advancing and leaves
mount(2) spinning in the kernel. Oversized values can also move the cursor
past the mapped OLT block without first rejecting the malformed image.

Reject malformed OLT header and record sizes before using them. A valid
header must place the first record after the header and within the mapped
OLT extent. Each record must be at least large enough to contain the common
record header and must fit in the remaining extent.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Sangho Lee <kudo3228@gmail.com>
---
 fs/freevxfs/vxfs_olt.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
index 23f35187c289..e5fb3b86d88e 100644
--- a/fs/freevxfs/vxfs_olt.c
+++ b/fs/freevxfs/vxfs_olt.c
@@ -56,6 +56,7 @@
 	struct buffer_head	*bp;
 	struct vxfs_olt		*op;
 	char			*oaddr, *eaddr;
+	u32			olt_size;
 
 	bp = sb_bread(sbp, vxfs_oblock(sbp, infp->vsi_oltext, bsize));
 	if (!bp || !bp->b_data)
@@ -77,12 +78,21 @@
 		goto fail;
 	}
 
-	oaddr = bp->b_data + fs32_to_cpu(infp, op->olt_size);
 	eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize);
+	olt_size = fs32_to_cpu(infp, op->olt_size);
+	if (olt_size < sizeof(*op) || olt_size > eaddr - bp->b_data) {
+		pr_notice("vxfs: invalid olt header size\n");
+		goto fail;
+	}
+	oaddr = bp->b_data + olt_size;
 
 	while (oaddr < eaddr) {
 		struct vxfs_oltcommon	*ocp =
 			(struct vxfs_oltcommon *)oaddr;
+		u32			rec_size = fs32_to_cpu(infp, ocp->olt_size);
+
+		if (rec_size < sizeof(*ocp) || rec_size > eaddr - oaddr)
+			goto fail;
 		
 		switch (fs32_to_cpu(infp, ocp->olt_type)) {
 		case VXFS_OLT_FSHEAD:
@@ -93,7 +103,11 @@
 			break;
 		}
 
-		oaddr += fs32_to_cpu(infp, ocp->olt_size);
+		/*
+		 * rec_size has already been checked to advance oaddr and stay
+		 * within the mapped OLT extent.
+		 */
+		oaddr += rec_size;
 	}
 
 	brelse(bp);
-- 
2.43.0

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

end of thread, other threads:[~2026-07-22 14:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-22 10:57 [PATCH] freevxfs: reject invalid OLT record sizes Sangho Lee
2026-07-22 12:10 ` Christoph Hellwig
2026-07-22 14:39   ` Sangho Lee

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®