mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 11:03:07 -04:00
ext4: fix buffer_head leak in ext4_init_orphan_info
ext4_init_orphan_info() reads orphan file blocks with ext4_bread()
and stores the returned buffer_head in oi->of_binfo[i].ob_bh.
If ext4_bread() succeeds but the orphan block magic or checksum
validation fails, the function jumps to out_free. However, the old
out_free loop starts releasing buffers from i - 1, so the current
buffer_head at index i is skipped.
This leaks the buffer_head reference obtained by ext4_bread() on the
bad magic and bad checksum error paths.
Fix this by tracking the number of successfully read buffer_heads and
releasing exactly those buffer_heads on the error path.
Fixes: 02f310fcf4 ("ext4: Speedup ext4 orphan inode handling")
Signed-off-by: Guanghui Yang <3497809730@qq.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/tencent_B38798612A159E21450ECF959016371B0807@qq.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
committed by
Theodore Ts'o
parent
409a7f12a0
commit
0570433580
@@ -572,6 +572,7 @@ int ext4_init_orphan_info(struct super_block *sb)
|
||||
int i, j;
|
||||
int ret;
|
||||
int free;
|
||||
int loaded = 0;
|
||||
__le32 *bdata;
|
||||
int inodes_per_ob = ext4_inodes_per_orphan_block(sb);
|
||||
struct ext4_orphan_block_tail *ot;
|
||||
@@ -613,6 +614,7 @@ int ext4_init_orphan_info(struct super_block *sb)
|
||||
ret = -EIO;
|
||||
goto out_free;
|
||||
}
|
||||
loaded++;
|
||||
ot = ext4_orphan_block_tail(sb, oi->of_binfo[i].ob_bh);
|
||||
if (le32_to_cpu(ot->ob_magic) != EXT4_ORPHAN_BLOCK_MAGIC) {
|
||||
ext4_error(sb, "orphan file block %d: bad magic", i);
|
||||
@@ -635,8 +637,10 @@ int ext4_init_orphan_info(struct super_block *sb)
|
||||
iput(inode);
|
||||
return 0;
|
||||
out_free:
|
||||
for (i--; i >= 0; i--)
|
||||
brelse(oi->of_binfo[i].ob_bh);
|
||||
while (loaded > 0) {
|
||||
loaded--;
|
||||
brelse(oi->of_binfo[loaded].ob_bh);
|
||||
}
|
||||
kvfree(oi->of_binfo);
|
||||
out_put:
|
||||
iput(inode);
|
||||
|
||||
Reference in New Issue
Block a user