ext4: fix memory leak in ext4_fill_super

Buffer head references must be released before calling kill_bdev();
otherwise the buffer head (and its page referenced by b_data) will not
be freed by kill_bdev, and subsequently that bh will be leaked.

If blocksizes differ, sb_set_blocksize() will kill current buffers and
page cache by using kill_bdev(). And then super block will be reread
again but using correct blocksize this time. sb_set_blocksize() didn't
fully free superblock page and buffer head, and being busy, they were
not freed and instead leaked.

This can easily be reproduced by calling an infinite loop of:

systemctl start <ext4_on_lvm>.mount, and
systemctl stop <ext4_on_lvm>.mount

... since systemd creates a cgroup for each slice which it mounts, and
the bh leak get amplified by a dying memory cgroup that also never
gets freed, and memory consumption is much more easily noticed.

Fixes: ce40733ce93d ("ext4: Check for return value from sb_set_blocksize")
Fixes: ac27a0ec112a ("ext4: initial copy of files from ext3")
Link: https://lore.kernel.org/r/20210521075533.95732-1-amakhalov@vmware.com
Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org

authored by Alexey Makhalov and committed by Theodore Ts'o afd09b61 a7ba36bc

Changed files
+9 -2
fs
ext4
+9 -2
fs/ext4/super.c
··· 4462 4462 } 4463 4463 4464 4464 if (sb->s_blocksize != blocksize) { 4465 + /* 4466 + * bh must be released before kill_bdev(), otherwise 4467 + * it won't be freed and its page also. kill_bdev() 4468 + * is called by sb_set_blocksize(). 4469 + */ 4470 + brelse(bh); 4465 4471 /* Validate the filesystem blocksize */ 4466 4472 if (!sb_set_blocksize(sb, blocksize)) { 4467 4473 ext4_msg(sb, KERN_ERR, "bad block size %d", 4468 4474 blocksize); 4475 + bh = NULL; 4469 4476 goto failed_mount; 4470 4477 } 4471 4478 4472 - brelse(bh); 4473 4479 logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE; 4474 4480 offset = do_div(logical_sb_block, blocksize); 4475 4481 bh = ext4_sb_bread_unmovable(sb, logical_sb_block); ··· 5208 5202 kfree(get_qf_name(sb, sbi, i)); 5209 5203 #endif 5210 5204 fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy); 5211 - ext4_blkdev_remove(sbi); 5205 + /* ext4_blkdev_remove() calls kill_bdev(), release bh before it. */ 5212 5206 brelse(bh); 5207 + ext4_blkdev_remove(sbi); 5213 5208 out_fail: 5214 5209 sb->s_fs_info = NULL; 5215 5210 kfree(sbi->s_blockgroup_lock);