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
1Patches
161bce219ee551ext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
7e807cb8603bext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
afc5e61e1a07ext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
4a79fde8db7eext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
2f4b1052246cext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
12615ab4bfb6ext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
bd7b52557e4aext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
ca81109d4a8fext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
ca81109d4a8fext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
bd7b52557e4aext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
2f4b1052246cext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
12615ab4bfb6ext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
1bce219ee551ext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
4a79fde8db7eext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
7e807cb8603bext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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
afc5e61e1a07ext4: fix memory leak in ext4_ext_shift_extents()
2 files changed · +4 −4
fs/ext4/extents.c+2 −2 modifieddiff --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 modifieddiff --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- git.kernel.org/stable/c/12615ab4bfb69678e5d961b28bb70040299e51b1nvd
- git.kernel.org/stable/c/1bce219ee5512cf179ba40cf114945a14a16e21fnvd
- git.kernel.org/stable/c/2f4b1052246ca646bb17bfe0f53df2fdf9729b58nvd
- git.kernel.org/stable/c/4a79fde8db7eba7f1128d971ceba4e3c9ac84aecnvd
- git.kernel.org/stable/c/7e807cb8603b7664fa630a696cd891d9a03c248dnvd
- git.kernel.org/stable/c/afc5e61e1a07b2b833bd72cbee36ecce9cd901e2nvd
- git.kernel.org/stable/c/bd7b52557e4a3ccd7595fdb3a585f1257de57935nvd
- git.kernel.org/stable/c/ca81109d4a8f192dc1cbad4a1ee25246363c2833nvd
News mentions
0No linked articles in our index yet.