VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-46072

CVE-2026-46072

Description

In the Linux kernel, the following vulnerability has been resolved:

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).

Affected products

1

Patches

10
bf7ac4a1d3bf

ntfs3: add buffer boundary checks to run_unpack()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitTobias GaertnerMar 29, 2026Fixed in 6.6.140via kernel-cna
2 files changed · +12 2
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 0256fa7c879ff2..568ce7ce4f00e1 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
     		if (size_size > 8)
     			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;
    @@ -975,6 +978,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
     		else if (offset_size <= 8) {
     			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);
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 0256fa7c879ff2..568ce7ce4f00e1 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
     		if (size_size > 8)
     			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;
    @@ -975,6 +978,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
     		else if (offset_size <= 8) {
     			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);
    -- 
    cgit 1.3-korg
    
    
    
b62567bca474

ntfs3: add buffer boundary checks to run_unpack()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitTobias GaertnerMar 29, 2026Fixed in 7.1-rc1via kernel-cna
2 files changed · +12 2
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index c0324cdc174dd0..29817ecb1c7d4f 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);
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index c0324cdc174dd0..29817ecb1c7d4f 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);
    -- 
    cgit 1.3-korg
    
    
    
e64f7dfcaff7

ntfs3: add buffer boundary checks to run_unpack()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitTobias GaertnerMar 29, 2026Fixed in 6.12.86via kernel-cna
2 files changed · +12 2
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 66fb690d775114..9f7e2eae03dcf6 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,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;
    @@ -975,6 +978,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);
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 66fb690d775114..9f7e2eae03dcf6 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,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;
    @@ -975,6 +978,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);
    -- 
    cgit 1.3-korg
    
    
    
41aadf5cb482

ntfs3: add buffer boundary checks to run_unpack()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitTobias GaertnerMar 29, 2026Fixed in 7.0.4via kernel-cna
2 files changed · +12 2
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index c0324cdc174dd0..29817ecb1c7d4f 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);
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index c0324cdc174dd0..29817ecb1c7d4f 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);
    -- 
    cgit 1.3-korg
    
    
    
d3012690a706

ntfs3: add buffer boundary checks to run_unpack()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitTobias GaertnerMar 29, 2026Fixed in 6.18.27via kernel-cna
2 files changed · +12 2
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 21decc2922823f..087c13a60c2057 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,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;
    @@ -975,6 +978,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);
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 21decc2922823f..087c13a60c2057 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,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;
    @@ -975,6 +978,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);
    -- 
    cgit 1.3-korg
    
    
    
41aadf5cb482

ntfs3: add buffer boundary checks to run_unpack()

2 files changed · +12 2
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index c0324cdc174dd0..29817ecb1c7d4f 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);
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index c0324cdc174dd0..29817ecb1c7d4f 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);
    -- 
    cgit 1.3-korg
    
    
    
d3012690a706

ntfs3: add buffer boundary checks to run_unpack()

2 files changed · +12 2
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 21decc2922823f..087c13a60c2057 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,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;
    @@ -975,6 +978,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);
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 21decc2922823f..087c13a60c2057 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,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;
    @@ -975,6 +978,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);
    -- 
    cgit 1.3-korg
    
    
    
e64f7dfcaff7

ntfs3: add buffer boundary checks to run_unpack()

2 files changed · +12 2
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 66fb690d775114..9f7e2eae03dcf6 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,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;
    @@ -975,6 +978,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);
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 66fb690d775114..9f7e2eae03dcf6 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,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;
    @@ -975,6 +978,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);
    -- 
    cgit 1.3-korg
    
    
    
b62567bca474

ntfs3: add buffer boundary checks to run_unpack()

2 files changed · +12 2
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index c0324cdc174dd0..29817ecb1c7d4f 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);
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index c0324cdc174dd0..29817ecb1c7d4f 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);
    -- 
    cgit 1.3-korg
    
    
    
bf7ac4a1d3bf

ntfs3: add buffer boundary checks to run_unpack()

2 files changed · +12 2
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 0256fa7c879ff2..568ce7ce4f00e1 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
     		if (size_size > 8)
     			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;
    @@ -975,6 +978,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
     		else if (offset_size <= 8) {
     			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);
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ntfs3/run.c+6 1 modified
    diff --git a/fs/ntfs3/run.c b/fs/ntfs3/run.c
    index 0256fa7c879ff2..568ce7ce4f00e1 100644
    --- a/fs/ntfs3/run.c
    +++ b/fs/ntfs3/run.c
    @@ -963,6 +963,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
     		if (size_size > 8)
     			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;
    @@ -975,6 +978,9 @@ int run_unpack(struct runs_tree *run, struct ntfs_sb_info *sbi, CLST ino,
     		else if (offset_size <= 8) {
     			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);
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing buffer boundary checks before reading variable-length fields in run_unpack() allows out-of-bounds heap read."

Attack vector

An attacker crafts a malicious NTFS image with truncated run data in an MFT attribute [patch_id=2659949]. When the filesystem is mounted, the kernel's `run_unpack()` function reads `size_size` and `offset_size` bytes from the run buffer without checking whether those bytes lie beyond the buffer end, causing an out-of-bounds heap read of up to 15 bytes [patch_id=2659949]. No special privileges are required beyond the ability to mount the crafted image (e.g., via a removable drive or a network filesystem).

Affected code

The vulnerability resides in the `run_unpack()` function in `fs/ntfs3/run.c` [patch_id=2659949]. The while-loop checks `run_buf < run_last` but then calls `run_unpack_s64(run_buf, size_size, 0)` and `run_unpack_s64(run_buf, offset_size, dlcn)` without verifying that `size_size` or `offset_size` bytes actually fit within the remaining buffer [patch_id=2659949].

What the fix does

The patch adds two boundary checks in `run_unpack()` before each `run_unpack_s64()` call [patch_id=2659949]. Before reading the `size_size` field, it checks `if (run_buf + size_size > run_last) return -EINVAL`; before reading the `offset_size` field, it checks `if (run_buf + offset_size > run_last) return -EINVAL` [patch_id=2659949]. These checks ensure the declared field size does not exceed the remaining buffer, preventing the out-of-bounds heap read.

Preconditions

  • inputAttacker must provide a crafted NTFS filesystem image with truncated run data in an MFT attribute
  • configThe image must be mounted on a system using the ntfs3 kernel driver

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.