[PATCH 1/2] ntfs3: add buffer boundary checks to run_unpack()

tobgaertner posted 2 patches 4 days, 1 hour ago
[PATCH 1/2] ntfs3: add buffer boundary checks to run_unpack()
Posted by tobgaertner 4 days, 1 hour ago
From: Tobias Gaertner <tob.gaertner@me.com>

run_unpack() checks `run_buf < run_last` at the top of the while loop
but then reads size_size and offset_size bytes via run_unpack_s64()
without verifying they fit within the remaining buffer.  A crafted NTFS
image with truncated run data in an MFT attribute triggers an OOB heap
read of up to 15 bytes when the filesystem is mounted.

Add boundary checks before each run_unpack_s64() call to ensure the
declared field size does not exceed the remaining buffer.

Found by fuzzing with a source-patched harness (LibAFL + QEMU).

Fixes: 82cae269cfa95 ("fs/ntfs3: Add initialization of super block")
Cc: stable@vger.kernel.org
Signed-off-by: Tobias Gaertner <tob.gaertner@me.com>
---
 fs/ntfs3/run.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
index 395b20492..c3c6917fa 100644
--- a/fs/ntfs3/run.c
+++ b/fs/ntfs3/run.c
@@ -970,6 +970,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
 		if (size_size > sizeof(len))
 			return -EINVAL;
 
+		if (run_buf + size_size > run_last)
+			return -EINVAL;
+
 		len = run_unpack_s64(run_buf, size_size, 0);
 		/* Skip size_size. */
 		run_buf += size_size;
@@ -982,6 +985,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
 		else if (offset_size <= sizeof(s64)) {
 			s64 dlcn;
 
+			if (run_buf + offset_size > run_last)
+				return -EINVAL;
+
 			/* Initial value of dlcn is -1 or 0. */
 			dlcn = (run_buf[offset_size - 1] & 0x80) ? (s64)-1 : 0;
 			dlcn = run_unpack_s64(run_buf, offset_size, dlcn);
-- 
2.43.0