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

CVE-2026-45899

CVE-2026-45899

Description

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

ext4: drop extent cache when splitting extent fails

When the split extent fails, we might leave some extents still being processed and return an error directly, which will result in stale extent entries remaining in the extent status tree. So drop all of the remaining potentially stale extents if the splitting fails.

AI Insight

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

In the Linux kernel's ext4 filesystem, a failure during extent splitting can leave stale entries in the extent status tree, potentially causing filesystem corruption.

Vulnerability

In the Linux kernel's ext4 filesystem, when an extent split operation fails, the code may return an error without cleaning up partially processed extents. This leaves stale entries in the extent status tree. The vulnerability affects all versions of the Linux kernel that include the ext4 filesystem code prior to the application of the fix.

Exploitation

An attacker with the ability to perform file operations on an ext4 filesystem can trigger the vulnerability by causing an extent split to fail. This could be achieved through conditions such as disk full, quota limits, or other I/O errors during file operations that require extent splitting. No special privileges beyond normal file access are required.

Impact

Successful exploitation results in stale extent entries remaining in the extent status tree. This can lead to filesystem corruption, data loss, or denial of service as the filesystem may operate on incorrect metadata.

Mitigation

The fix is to drop all remaining potentially stale extents when a split fails. The patch is included in the Linux kernel stable releases via commits referenced in the CVE. Users should update to a kernel version containing these commits. No workaround is available 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

14
6e54f8dfee35

ext4: drop extent cache when splitting extent fails

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZhang YiFeb 25, 2026Fixed in 5.10.253via kernel-cna
2 files changed · +16 6
  • fs/ext4/extents.c+8 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index e5b32d5f634a20..6d37805d315507 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3231,7 +3231,9 @@ static int ext4_split_extent_at(handle_t *handle,
     		ext4_ext_mark_unwritten(ex2);
     
     	err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
    -	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +	if (err && err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +		goto out_err;
    +	if (!err)
     		goto out;
     
     	/*
    @@ -3247,7 +3249,8 @@ static int ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return PTR_ERR(path);
    +		err = PTR_ERR(path);
    +		goto out_err;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3303,6 +3306,9 @@ fix_extent_len:
     	 */
     	ext4_ext_dirty(handle, inode, path + path->p_depth);
     	return err;
    +out_err:
    +	/* Remove all remaining potentially stale extents. */
    +	ext4_es_remove_extent(inode, ee_block, ee_len);
     out:
     	ext4_ext_show_leaf(inode, *ppath);
     	return err;
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+8 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index e5b32d5f634a20..6d37805d315507 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3231,7 +3231,9 @@ static int ext4_split_extent_at(handle_t *handle,
     		ext4_ext_mark_unwritten(ex2);
     
     	err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
    -	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +	if (err && err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +		goto out_err;
    +	if (!err)
     		goto out;
     
     	/*
    @@ -3247,7 +3249,8 @@ static int ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return PTR_ERR(path);
    +		err = PTR_ERR(path);
    +		goto out_err;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3303,6 +3306,9 @@ fix_extent_len:
     	 */
     	ext4_ext_dirty(handle, inode, path + path->p_depth);
     	return err;
    +out_err:
    +	/* Remove all remaining potentially stale extents. */
    +	ext4_es_remove_extent(inode, ee_block, ee_len);
     out:
     	ext4_ext_show_leaf(inode, *ppath);
     	return err;
    -- 
    cgit 1.3-korg
    
    
    
337506dc6523

ext4: drop extent cache when splitting extent fails

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZhang YiFeb 25, 2026Fixed in 5.15.203via kernel-cna
2 files changed · +16 6
  • fs/ext4/extents.c+8 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 54df6fe69d792f..80b7783c65b41e 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3236,7 +3236,9 @@ static int ext4_split_extent_at(handle_t *handle,
     		ext4_ext_mark_unwritten(ex2);
     
     	err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
    -	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +	if (err && err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +		goto out_err;
    +	if (!err)
     		goto out;
     
     	/*
    @@ -3252,7 +3254,8 @@ static int ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return PTR_ERR(path);
    +		err = PTR_ERR(path);
    +		goto out_err;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3308,6 +3311,9 @@ fix_extent_len:
     	 */
     	ext4_ext_dirty(handle, inode, path + path->p_depth);
     	return err;
    +out_err:
    +	/* Remove all remaining potentially stale extents. */
    +	ext4_es_remove_extent(inode, ee_block, ee_len);
     out:
     	ext4_ext_show_leaf(inode, *ppath);
     	return err;
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+8 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 54df6fe69d792f..80b7783c65b41e 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3236,7 +3236,9 @@ static int ext4_split_extent_at(handle_t *handle,
     		ext4_ext_mark_unwritten(ex2);
     
     	err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
    -	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +	if (err && err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +		goto out_err;
    +	if (!err)
     		goto out;
     
     	/*
    @@ -3252,7 +3254,8 @@ static int ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return PTR_ERR(path);
    +		err = PTR_ERR(path);
    +		goto out_err;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3308,6 +3311,9 @@ fix_extent_len:
     	 */
     	ext4_ext_dirty(handle, inode, path + path->p_depth);
     	return err;
    +out_err:
    +	/* Remove all remaining potentially stale extents. */
    +	ext4_es_remove_extent(inode, ee_block, ee_len);
     out:
     	ext4_ext_show_leaf(inode, *ppath);
     	return err;
    -- 
    cgit 1.3-korg
    
    
    
808f3191498f

ext4: drop extent cache when splitting extent fails

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZhang YiNov 29, 2025Fixed in 6.18.14via kernel-cna
2 files changed · +12 6
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 37d02e5bbc936a..7402271003fa82 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 37d02e5bbc936a..7402271003fa82 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
79b592e8f1b4

ext4: drop extent cache when splitting extent fails

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZhang YiNov 29, 2025Fixed in 7.0via kernel-cna
2 files changed · +12 6
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 1094e492345132..945995d68c4d34 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 1094e492345132..945995d68c4d34 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
31bf37cf53ed

ext4: drop extent cache when splitting extent fails

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZhang YiNov 29, 2025Fixed in 6.19.4via kernel-cna
2 files changed · +12 6
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index eebb22586163f1..fb3ebfac1b33d1 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index eebb22586163f1..fb3ebfac1b33d1 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
dc7c9b9d03a5

ext4: drop extent cache when splitting extent fails

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZhang YiNov 29, 2025Fixed in 6.6.130via kernel-cna
2 files changed · +12 6
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 2818d297ce464f..b7e9cbe832121f 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3250,7 +3250,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3264,7 +3264,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3341,6 +3341,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 2818d297ce464f..b7e9cbe832121f 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3250,7 +3250,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3264,7 +3264,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3341,6 +3341,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
120c6bd7ca9d

ext4: drop extent cache when splitting extent fails

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitZhang YiNov 29, 2025Fixed in 6.12.75via kernel-cna
2 files changed · +12 6
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 9ffdf30eb4fef8..36e42640629705 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3265,7 +3265,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3279,7 +3279,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3356,6 +3356,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 9ffdf30eb4fef8..36e42640629705 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3265,7 +3265,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3279,7 +3279,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3356,6 +3356,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
6e54f8dfee35

ext4: drop extent cache when splitting extent fails

2 files changed · +16 6
  • fs/ext4/extents.c+8 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index e5b32d5f634a20..6d37805d315507 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3231,7 +3231,9 @@ static int ext4_split_extent_at(handle_t *handle,
     		ext4_ext_mark_unwritten(ex2);
     
     	err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
    -	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +	if (err && err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +		goto out_err;
    +	if (!err)
     		goto out;
     
     	/*
    @@ -3247,7 +3249,8 @@ static int ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return PTR_ERR(path);
    +		err = PTR_ERR(path);
    +		goto out_err;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3303,6 +3306,9 @@ fix_extent_len:
     	 */
     	ext4_ext_dirty(handle, inode, path + path->p_depth);
     	return err;
    +out_err:
    +	/* Remove all remaining potentially stale extents. */
    +	ext4_es_remove_extent(inode, ee_block, ee_len);
     out:
     	ext4_ext_show_leaf(inode, *ppath);
     	return err;
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+8 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index e5b32d5f634a20..6d37805d315507 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3231,7 +3231,9 @@ static int ext4_split_extent_at(handle_t *handle,
     		ext4_ext_mark_unwritten(ex2);
     
     	err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
    -	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +	if (err && err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +		goto out_err;
    +	if (!err)
     		goto out;
     
     	/*
    @@ -3247,7 +3249,8 @@ static int ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return PTR_ERR(path);
    +		err = PTR_ERR(path);
    +		goto out_err;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3303,6 +3306,9 @@ fix_extent_len:
     	 */
     	ext4_ext_dirty(handle, inode, path + path->p_depth);
     	return err;
    +out_err:
    +	/* Remove all remaining potentially stale extents. */
    +	ext4_es_remove_extent(inode, ee_block, ee_len);
     out:
     	ext4_ext_show_leaf(inode, *ppath);
     	return err;
    -- 
    cgit 1.3-korg
    
    
    
337506dc6523

ext4: drop extent cache when splitting extent fails

2 files changed · +16 6
  • fs/ext4/extents.c+8 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 54df6fe69d792f..80b7783c65b41e 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3236,7 +3236,9 @@ static int ext4_split_extent_at(handle_t *handle,
     		ext4_ext_mark_unwritten(ex2);
     
     	err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
    -	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +	if (err && err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +		goto out_err;
    +	if (!err)
     		goto out;
     
     	/*
    @@ -3252,7 +3254,8 @@ static int ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return PTR_ERR(path);
    +		err = PTR_ERR(path);
    +		goto out_err;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3308,6 +3311,9 @@ fix_extent_len:
     	 */
     	ext4_ext_dirty(handle, inode, path + path->p_depth);
     	return err;
    +out_err:
    +	/* Remove all remaining potentially stale extents. */
    +	ext4_es_remove_extent(inode, ee_block, ee_len);
     out:
     	ext4_ext_show_leaf(inode, *ppath);
     	return err;
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+8 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 54df6fe69d792f..80b7783c65b41e 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3236,7 +3236,9 @@ static int ext4_split_extent_at(handle_t *handle,
     		ext4_ext_mark_unwritten(ex2);
     
     	err = ext4_ext_insert_extent(handle, inode, ppath, &newex, flags);
    -	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +	if (err && err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    +		goto out_err;
    +	if (!err)
     		goto out;
     
     	/*
    @@ -3252,7 +3254,8 @@ static int ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return PTR_ERR(path);
    +		err = PTR_ERR(path);
    +		goto out_err;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3308,6 +3311,9 @@ fix_extent_len:
     	 */
     	ext4_ext_dirty(handle, inode, path + path->p_depth);
     	return err;
    +out_err:
    +	/* Remove all remaining potentially stale extents. */
    +	ext4_es_remove_extent(inode, ee_block, ee_len);
     out:
     	ext4_ext_show_leaf(inode, *ppath);
     	return err;
    -- 
    cgit 1.3-korg
    
    
    
808f3191498f

ext4: drop extent cache when splitting extent fails

2 files changed · +12 6
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 37d02e5bbc936a..7402271003fa82 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 37d02e5bbc936a..7402271003fa82 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
31bf37cf53ed

ext4: drop extent cache when splitting extent fails

2 files changed · +12 6
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index eebb22586163f1..fb3ebfac1b33d1 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index eebb22586163f1..fb3ebfac1b33d1 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
120c6bd7ca9d

ext4: drop extent cache when splitting extent fails

2 files changed · +12 6
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 9ffdf30eb4fef8..36e42640629705 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3265,7 +3265,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3279,7 +3279,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3356,6 +3356,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 9ffdf30eb4fef8..36e42640629705 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3265,7 +3265,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3279,7 +3279,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3356,6 +3356,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
dc7c9b9d03a5

ext4: drop extent cache when splitting extent fails

2 files changed · +12 6
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 2818d297ce464f..b7e9cbe832121f 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3250,7 +3250,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3264,7 +3264,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3341,6 +3341,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 2818d297ce464f..b7e9cbe832121f 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3250,7 +3250,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3264,7 +3264,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3341,6 +3341,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
79b592e8f1b4

ext4: drop extent cache when splitting extent fails

2 files changed · +12 6
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 1094e492345132..945995d68c4d34 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    
  • fs/ext4/extents.c+6 3 modified
    diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
    index 1094e492345132..945995d68c4d34 100644
    --- a/fs/ext4/extents.c
    +++ b/fs/ext4/extents.c
    @@ -3267,7 +3267,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     
     	err = PTR_ERR(path);
     	if (err != -ENOSPC && err != -EDQUOT && err != -ENOMEM)
    -		return path;
    +		goto out_path;
     
     	/*
     	 * Get a new path to try to zeroout or fix the extent length.
    @@ -3281,7 +3281,7 @@ static struct ext4_ext_path *ext4_split_extent_at(handle_t *handle,
     	if (IS_ERR(path)) {
     		EXT4_ERROR_INODE(inode, "Failed split extent on %u, err %ld",
     				 split, PTR_ERR(path));
    -		return path;
    +		goto out_path;
     	}
     	depth = ext_depth(inode);
     	ex = path[depth].p_ext;
    @@ -3358,6 +3358,10 @@ out:
     		ext4_free_ext_path(path);
     		path = ERR_PTR(err);
     	}
    +out_path:
    +	if (IS_ERR(path))
    +		/* Remove all remaining potentially stale extents. */
    +		ext4_es_remove_extent(inode, ee_block, ee_len);
     	ext4_ext_show_leaf(inode, path);
     	return path;
     }
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing cleanup of the extent status tree when ext4_split_extent_at() fails after partially processing extents, leaving stale entries."

Attack vector

An attacker with the ability to trigger filesystem operations that cause extent splitting (e.g., fallocate, write on a fragmented file) on an ext4 filesystem can provoke a failure in ext4_ext_insert_extent() or in a subsequent retry path. When the split fails, the function previously returned an error without removing the extent entries that had already been inserted into the inode's extent status tree. This leaves stale cached extent entries that can cause subsequent I/O to read or write from incorrect disk blocks, potentially leading to data corruption or information disclosure. No special network access is required; the attack vector is local filesystem operations.

Affected code

The vulnerability is in `fs/ext4/extents.c` in the function `ext4_split_extent_at()`. The patch modifies the error handling after `ext4_ext_insert_extent()` and after the `IS_ERR(path)` check to redirect to a new cleanup label instead of returning immediately.

What the fix does

The patch adds a new error-handling label `out_err` (or `out_path` in the upstream variant) that calls `ext4_es_remove_extent(inode, ee_block, ee_len)` to drop all potentially stale extent cache entries before returning the error. In the `ext4_split_extent_at()` function, two early-return paths that previously bypassed cleanup now jump to this new label. The change ensures that whenever the extent split fails after partial progress, the extent status tree is cleaned up, preventing stale cached entries from persisting.

Preconditions

  • inputAttacker must be able to perform filesystem operations that trigger extent splitting on an ext4 filesystem (e.g., fallocate, writes to fragmented files).
  • configThe filesystem must be mounted and the inode must be in a state where extent splitting can be attempted.

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

References

7

News mentions

0

No linked articles in our index yet.