mirror of
https://github.com/raspberrypi/linux.git
synced 2026-01-05 10:47:34 +00:00
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
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -1712,18 +1712,26 @@ static int writeback_single_inode(struct inode *inode,
|
||||
wb = inode_to_wb_and_lock_list(inode);
|
||||
spin_lock(&inode->i_lock);
|
||||
/*
|
||||
* If the inode is now fully clean, then it can be safely removed from
|
||||
* its writeback list (if any). Otherwise the flusher threads are
|
||||
* responsible for the writeback lists.
|
||||
* If the inode is freeing, its i_io_list shoudn't be updated
|
||||
* as it can be finally deleted at this moment.
|
||||
*/
|
||||
if (!(inode->i_state & I_DIRTY_ALL))
|
||||
inode_cgwb_move_to_attached(inode, wb);
|
||||
else if (!(inode->i_state & I_SYNC_QUEUED)) {
|
||||
if ((inode->i_state & I_DIRTY))
|
||||
redirty_tail_locked(inode, wb);
|
||||
else if (inode->i_state & I_DIRTY_TIME) {
|
||||
inode->dirtied_when = jiffies;
|
||||
inode_io_list_move_locked(inode, wb, &wb->b_dirty_time);
|
||||
if (!(inode->i_state & I_FREEING)) {
|
||||
/*
|
||||
* If the inode is now fully clean, then it can be safely
|
||||
* removed from its writeback list (if any). Otherwise the
|
||||
* flusher threads are responsible for the writeback lists.
|
||||
*/
|
||||
if (!(inode->i_state & I_DIRTY_ALL))
|
||||
inode_cgwb_move_to_attached(inode, wb);
|
||||
else if (!(inode->i_state & I_SYNC_QUEUED)) {
|
||||
if ((inode->i_state & I_DIRTY))
|
||||
redirty_tail_locked(inode, wb);
|
||||
else if (inode->i_state & I_DIRTY_TIME) {
|
||||
inode->dirtied_when = jiffies;
|
||||
inode_io_list_move_locked(inode,
|
||||
wb,
|
||||
&wb->b_dirty_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user