diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-11-24 10:22:42 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-11-24 10:22:42 -0800 |
| commit | 6fd2152fd1ff9a5ea488674a97af396e4047eaed (patch) | |
| tree | 24a698120ec659eef7cfa86ca6afd9c8802bf263 /fs/ext4/extents.c | |
| parent | c3eb11fbb826879be773c137f281569efce67aa8 (diff) | |
| parent | 4e3c51f4e805291b057d12f5dda5aeb50a538dc4 (diff) | |
| download | linux-6fd2152fd1ff9a5ea488674a97af396e4047eaed.tar.gz linux-6fd2152fd1ff9a5ea488674a97af396e4047eaed.tar.bz2 linux-6fd2152fd1ff9a5ea488674a97af396e4047eaed.zip | |
Merge tag 'ext4_for_linus_stable2' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 fixes from Ted Ts'o:
"Fix a regression in the lazytime code that was introduced in v6.1-rc1,
and a use-after-free that can be triggered by a maliciously corrupted
file system"
* tag 'ext4_for_linus_stable2' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
fs: do not update freeing inode i_io_list
ext4: fix use-after-free in ext4_ext_shift_extents
Diffstat (limited to 'fs/ext4/extents.c')
| -rw-r--r-- | fs/ext4/extents.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index f1956288307f..6c399a8b22b3 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -5184,6 +5184,7 @@ ext4_ext_shift_extents(struct inode *inode, handle_t *handle, * and it is decreased till we reach start. */ again: + ret = 0; if (SHIFT == SHIFT_LEFT) iterator = &start; else @@ -5227,14 +5228,21 @@ again: ext4_ext_get_actual_len(extent); } else { extent = EXT_FIRST_EXTENT(path[depth].p_hdr); - if (le32_to_cpu(extent->ee_block) > 0) + if (le32_to_cpu(extent->ee_block) > start) *iterator = le32_to_cpu(extent->ee_block) - 1; - else - /* Beginning is reached, end of the loop */ + else if (le32_to_cpu(extent->ee_block) == start) iterator = NULL; - /* Update path extent in case we need to stop */ - while (le32_to_cpu(extent->ee_block) < start) + else { + extent = EXT_LAST_EXTENT(path[depth].p_hdr); + while (le32_to_cpu(extent->ee_block) >= start) + extent--; + + if (extent == EXT_LAST_EXTENT(path[depth].p_hdr)) + break; + extent++; + iterator = NULL; + } path[depth].p_ext = extent; } ret = ext4_ext_shift_path_extents(path, shift, inode, |
