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. -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEK2m5VNv+CHkogTfJ8vlZVpUNgaMFAmN+1NoACgkQ8vlZVpUN gaNY8Qf/ZJyI8JZTEyrd7KxM1S6eDwUth1kYsQQtqQojd5tTqYOsslSiTp2Yw+LI 4Gw75tDiMA6CYt+BuvbbgOk36YXaPW69sB+uParL/hgK005R50raQZ7oMdjQba4Z ODa+x27r5SVZIrcEAcHX15+BcjeCDZ/e5RMsV37ww+LsKNlnWNYn4o3S6eIv1ERo 0iqgasbaaATCy37gStRvtnbsyPWDdwL5XlJg0XnqFLzo6Yz1NMcXaxEZehyCaCSc SixkjSR1gafQu/0ZTdVaH1vXQPmFwCEMOGONdbb+FrQGnIBFv/kvgXeTKTkjOP1+ 2GV7UgdPXeUNECTrMBieEpxsLqpcZw== =8ya6 -----END PGP SIGNATURE----- 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:
commit
6fd2152fd1
2 changed files with 32 additions and 16 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue