lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: 
 <20250418-ensure-enough-bytes-inhfs_bnode_read_u16-v1-1-8733ad14d0fe@arnaud-lcm.com>
Date: Fri, 18 Apr 2025 14:33:15 +0200
From: Arnaud Lecomte <contact@...aud-lcm.com>
To: linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
 contact@...aud-lcm.com, skhan@...uxfoundation.org,
 syzbot+5405d1265a66aa313343@...kaller.appspotmail.com
Subject: [PATCH] hfs: Ensure enough bytes read in hfs_bnode_read_u16

In certain scenarios, hfs_bnode_read() may be called with an offset that
lands exactly at the end of a memory page (e.g. offset + page_offset == 4095).
This causes the read to span a page boundary, but hfs_bnode_read() is only
able to read the first byte before reaching the end of the node's page range.

As a result, the local variable `data` in hfs_bnode_read_u16() may be only
partially initialized, triggering a KASAN warning due to the use of
uninitialized stack memory.

Ensure that hfs_bnode_read() fully reads the requested number of bytes, or
handle the case where it cannot to prevent use of partially initialized data.

Reported-by: syzbot+5405d1265a66aa313343@...kaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=5405d1265a66aa313343
Tested-by: syzbot+5405d1265a66aa313343@...kaller.appspotmail.com
Fixes: 8ffd015db85f ("Linux 6.15-rc2")
Signed-off-by: Arnaud Lecomte <contact@...aud-lcm.com>
---
 fs/hfs/bnode.c | 9 ++++++---
 fs/hfs/btree.h | 2 +-
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/fs/hfs/bnode.c b/fs/hfs/bnode.c
index 6add6ebfef89..e8d7431ce178 100644
--- a/fs/hfs/bnode.c
+++ b/fs/hfs/bnode.c
@@ -15,7 +15,7 @@
 
 #include "btree.h"
 
-void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
+int hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
 {
 	struct page *page;
 	int pagenum;
@@ -37,13 +37,16 @@ void hfs_bnode_read(struct hfs_bnode *node, void *buf, int off, int len)
 		pagenum++;
 		off = 0; /* page offset only applies to the first page */
 	}
+
+	return bytes_to_read;
 }
 
 u16 hfs_bnode_read_u16(struct hfs_bnode *node, int off)
 {
-	__be16 data;
+	__be16 data = 0;
 	// optimize later...
-	hfs_bnode_read(node, &data, off, 2);
+	if(hfs_bnode_read(node, &data, off, 2) < sizeof(u16))
+		return 0;
 	return be16_to_cpu(data);
 }
 
diff --git a/fs/hfs/btree.h b/fs/hfs/btree.h
index 0e6baee93245..54f310c52643 100644
--- a/fs/hfs/btree.h
+++ b/fs/hfs/btree.h
@@ -94,7 +94,7 @@ extern struct hfs_bnode * hfs_bmap_alloc(struct hfs_btree *);
 extern void hfs_bmap_free(struct hfs_bnode *node);
 
 /* bnode.c */
-extern void hfs_bnode_read(struct hfs_bnode *, void *, int, int);
+extern int hfs_bnode_read(struct hfs_bnode *, void *, int, int);
 extern u16 hfs_bnode_read_u16(struct hfs_bnode *, int);
 extern u8 hfs_bnode_read_u8(struct hfs_bnode *, int);
 extern void hfs_bnode_read_key(struct hfs_bnode *, void *, int);

---
base-commit: 8ffd015db85fea3e15a77027fda6c02ced4d2444
change-id: 20250418-ensure-enough-bytes-inhfs_bnode_read_u16-00380affd0ce

Best regards,
-- 
Arnaud Lecomte <contact@...aud-lcm.com>


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ