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

CVE-2026-45948

CVE-2026-45948

Description

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

ext4: fix memory leak in ext4_ext_shift_extents()

In ext4_ext_shift_extents(), if the extent is NULL in the while loop, the function returns immediately without releasing the path obtained via ext4_find_extent(), leading to a memory leak.

Fix this by jumping to the out label to ensure the path is properly released.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Memory leak in ext4's ext4_ext_shift_extents() when extent is NULL; fix ensures path release via out label.

Vulnerability

In the Linux kernel's ext4 filesystem, the function ext4_ext_shift_extents() contains a memory leak. When the extent pointer becomes NULL during the while loop, the function returns immediately without releasing the path structure obtained via ext4_find_extent(), resulting in a memory leak. Affected versions include all kernels before the fix commit [1].

Exploitation

An attacker with the ability to trigger file operations that cause ext4_ext_shift_extents() to be invoked with an extent that becomes NULL can exploit this vulnerability. The attacker must be able to perform operations such as file truncation, fallocate, or defragmentation that exercise the extent shifting code path. No special privileges are required beyond those needed to perform the triggering operation.

Impact

Successful exploitation leads to a kernel memory leak, which can cause resource exhaustion and system degradation over time, potentially resulting in a denial of service (DoS). The attacker does not gain elevated privileges or code execution; the impact is limited to availability.

Mitigation

The fix is included in Linux kernel commit bd7b52557e4a [1]. Users should update their kernel to a version that includes this commit or backport the patch. There is no known workaround other than applying the patch.

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

16
1bce219ee551

ext4: fix memory leak in ext4_ext_shift_extents()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 25, 2025Fixed in 6.1.165via kernel-cna
2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 1398da08fd5a38..1df71747746942 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5262,7 +5262,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 1398da08fd5a38..1df71747746942 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5262,7 +5262,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
7e807cb8603b

ext4: fix memory leak in ext4_ext_shift_extents()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 25, 2025Fixed in 5.10.252via kernel-cna
2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index eb3ae1c913c4f4..b0e8711fd7fd8b 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5261,7 +5261,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index eb3ae1c913c4f4..b0e8711fd7fd8b 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5261,7 +5261,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
afc5e61e1a07

ext4: fix memory leak in ext4_ext_shift_extents()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 25, 2025Fixed in 5.15.202via kernel-cna
2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 79d50c1d2e7bc5..fd2a096d8ba6a6 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5268,7 +5268,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 79d50c1d2e7bc5..fd2a096d8ba6a6 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5268,7 +5268,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
4a79fde8db7e

ext4: fix memory leak in ext4_ext_shift_extents()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 25, 2025Fixed in 6.6.128via kernel-cna
2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index e8012e0c777e8e..8d9cd6574d3265 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5258,7 +5258,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index e8012e0c777e8e..8d9cd6574d3265 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5258,7 +5258,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
2f4b1052246c

ext4: fix memory leak in ext4_ext_shift_extents()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 25, 2025Fixed in 6.12.75via kernel-cna
2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 36e42640629705..e309db1c15827b 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5249,7 +5249,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 36e42640629705..e309db1c15827b 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5249,7 +5249,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
12615ab4bfb6

ext4: fix memory leak in ext4_ext_shift_extents()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 25, 2025Fixed in 6.18.14via kernel-cna
2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 7402271003fa82..ae7f2d6b32e32e 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5410,7 +5410,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 7402271003fa82..ae7f2d6b32e32e 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5410,7 +5410,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
bd7b52557e4a

ext4: fix memory leak in ext4_ext_shift_extents()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 25, 2025Fixed in 6.19.4via kernel-cna
2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index fb3ebfac1b33d1..18b39eed752670 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5414,7 +5414,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index fb3ebfac1b33d1..18b39eed752670 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5414,7 +5414,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
ca81109d4a8f

ext4: fix memory leak in ext4_ext_shift_extents()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZilin GuanDec 25, 2025Fixed in 7.0via kernel-cna
2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 27eb2c1df01283..e0295e0339b496 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5406,7 +5406,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 27eb2c1df01283..e0295e0339b496 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5406,7 +5406,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
ca81109d4a8f

ext4: fix memory leak in ext4_ext_shift_extents()

2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 27eb2c1df01283..e0295e0339b496 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5406,7 +5406,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 27eb2c1df01283..e0295e0339b496 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5406,7 +5406,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
bd7b52557e4a

ext4: fix memory leak in ext4_ext_shift_extents()

2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index fb3ebfac1b33d1..18b39eed752670 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5414,7 +5414,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index fb3ebfac1b33d1..18b39eed752670 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5414,7 +5414,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
2f4b1052246c

ext4: fix memory leak in ext4_ext_shift_extents()

2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 36e42640629705..e309db1c15827b 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5249,7 +5249,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 36e42640629705..e309db1c15827b 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5249,7 +5249,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
12615ab4bfb6

ext4: fix memory leak in ext4_ext_shift_extents()

2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 7402271003fa82..ae7f2d6b32e32e 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5410,7 +5410,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 7402271003fa82..ae7f2d6b32e32e 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5410,7 +5410,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
1bce219ee551

ext4: fix memory leak in ext4_ext_shift_extents()

2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 1398da08fd5a38..1df71747746942 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5262,7 +5262,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 1398da08fd5a38..1df71747746942 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5262,7 +5262,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
4a79fde8db7e

ext4: fix memory leak in ext4_ext_shift_extents()

2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index e8012e0c777e8e..8d9cd6574d3265 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5258,7 +5258,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index e8012e0c777e8e..8d9cd6574d3265 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5258,7 +5258,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
7e807cb8603b

ext4: fix memory leak in ext4_ext_shift_extents()

2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index eb3ae1c913c4f4..b0e8711fd7fd8b 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5261,7 +5261,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index eb3ae1c913c4f4..b0e8711fd7fd8b 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5261,7 +5261,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
afc5e61e1a07

ext4: fix memory leak in ext4_ext_shift_extents()

2 files changed · +4 4
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 79d50c1d2e7bc5..fd2a096d8ba6a6 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5268,7 +5268,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+2 2 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 79d50c1d2e7bc5..fd2a096d8ba6a6 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -5268,7 +5268,8 @@ again:
     		if (!extent) {
     			EXT4_ERROR_INODE(inode, "unexpected hole at %lu",
     					 (unsigned long) *iterator);
    -			return -EFSCORRUPTED;
    +			ret = -EFSCORRUPTED;
    +			goto out;
     		}
     		if (SHIFT == SHIFT_LEFT && *iterator >
     		    le32_to_cpu(extent->ee_block)) {
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing resource release: when `ext4_find_extent()` returns a NULL extent inside the while loop of `ext4_ext_shift_extents()`, the function returns immediately without freeing the previously allocated path structure, causing a memory leak."

Attack vector

An attacker with the ability to trigger ext4 extent-shifting operations (e.g., via fallocate or other file-system operations that call `ext4_ext_shift_extents()`) on a corrupted or specially crafted ext4 filesystem can cause the kernel to encounter an unexpected hole in the extent tree. When `ext4_find_extent()` returns NULL for the extent at the current iterator position, the function logs an error and returns `-EFSCORRUPTED` without releasing the path object obtained earlier in the same call, leaking kernel memory. Repeated triggering of this code path can exhaust kernel memory, leading to a denial-of-service condition.

Affected code

The vulnerability is in the function `ext4_ext_shift_extents()` in `fs/ext4/extents.c`. The while loop at the `again:` label calls `ext4_find_extent()` to obtain a path, then checks if the returned extent pointer is NULL. Before the patch, the NULL check used a direct `return -EFSCORRUPTED;` which skipped the cleanup code at the `out` label [patch_id=2661089].

What the fix does

The patch changes the early-return path from `return -EFSCORRUPTED;` to `ret = -EFSCORRUPTED; goto out;` [patch_id=2661089]. The `out` label is the function's existing cleanup point that calls `ext4_ext_drop_refs(path)` and `kfree(path)`, ensuring the path allocated by `ext4_find_extent()` is always released before returning. This closes the memory leak that occurred when a NULL extent was detected in the while loop.

Preconditions

  • inputThe attacker must be able to trigger ext4 extent-shifting operations (e.g., via fallocate or other file operations) on an ext4 filesystem that contains or can be made to contain an unexpected hole in the extent tree.
  • authThe attacker needs local access to the system with sufficient privileges to perform file operations on an ext4 filesystem.

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

References

8

News mentions

0

No linked articles in our index yet.