summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Gaertner <tob.gaertner@me.com>2026-03-29 14:17:02 +0300
committerKonstantin Komarov <almaz.alexandrovich@paragon-software.com>2026-04-07 19:43:38 +0300
commitb62567bca47408e6739dee75f02a2113548af875 (patch)
treefb1555f3bf7e5450253ae93140c85a52f2420e73
parent6d979b64287fb051642fe0101f28c839be8ca837 (diff)
downloadlinux-b62567bca47408e6739dee75f02a2113548af875.tar.xz
ntfs3: add buffer boundary checks to run_unpack()
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> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
-rw-r--r--fs/ntfs3/run.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
index c0324cdc174d..29817ecb1c7d 100644
--- a/fs/ntfs3/run.c
+++ b/fs/ntfs3/run.c
@@ -1008,6 +1008,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;
@@ -1020,6 +1023,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);