On Jul 4, 2022, at 8:27 AM, Lukas Czerner <lczerner@xxxxxxxxxx> wrote: > > Currently ext4 directory handling code implicitly assumes that the > directory blocks are always within the i_size. In fact ext4_append() > will attempt to allocate next directory block based solely on i_size and > the i_size is then appropriately increased after a successful > allocation. > > However, for this to work it requires i_size to be correct. If, for any > reason, the directory inode i_size is corrupted in a way that the > directory tree refers to a valid directory block past i_size, we could > end up corrupting parts of the directory tree structure by overwriting > already used directory blocks when modifying the directory. > > Fix it by catching the corruption early in __ext4_read_dirblock(). > > Signed-off-by: Lukas Czerner <lczerner@xxxxxxxxxx> Reviewed-by: Andreas Dilger <adilger@xxxxxxxxx> > Addresses Red-Hat-Bugzilla: #2070205 > Cc: stable@xxxxxxxxxxxxxxx > --- > fs/ext4/namei.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c > index db4ba99d1ceb..cf460aa4f81d 100644 > --- a/fs/ext4/namei.c > +++ b/fs/ext4/namei.c > @@ -110,6 +110,13 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode, > struct ext4_dir_entry *dirent; > int is_dx_block = 0; > > + if (block >= inode->i_size) { > + ext4_error_inode(inode, func, line, block, > + "Attempting to read directory block (%u) that is past i_size (%llu)", > + block, inode->i_size); > + return ERR_PTR(-EFSCORRUPTED); > + } > + > if (ext4_simulate_fail(inode->i_sb, EXT4_SIM_DIRBLOCK_EIO)) > bh = ERR_PTR(-EIO); > else > -- > 2.35.3 > Cheers, Andreas
Attachment:
signature.asc
Description: Message signed with OpenPGP