diff options
author | Ritesh Harjani <riteshh@linux.ibm.com> | 2020-05-10 08:24:49 +0200 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2020-06-04 05:16:52 +0200 |
commit | eb2b8ebb867fa895d5c4768310998bc940f6506c (patch) | |
tree | 79a7a2e2c068c0ea6d0097b4148c0bc0c0b173e9 | |
parent | ext4: mballoc: refactor code inside DOUBLE_CHECK into separate function (diff) | |
download | linux-eb2b8ebb867fa895d5c4768310998bc940f6506c.tar.xz linux-eb2b8ebb867fa895d5c4768310998bc940f6506c.zip |
ext4: mballoc: fix possible NULL ptr & remove BUG_ONs from DOUBLE_CHECK
Make sure to check for e4b->bd_info->bb_bitmap == NULL, in
mb_cmp_bitmaps() and return if NULL, to avoid possible NULL ptr
dereference. Similar to how we do this in other ifdef DOUBLE_CHECK
functions.
Also remove the BUG_ON() logic if kmalloc() or ext4_read_block_bitmap()
fails. We should simply mark grp->bb_bitmap as NULL if above happens.
In fact ext4_read_block_bitmap() may even return an error in case of resize
ioctl. Hence remove this BUG_ON logic (fstests ext4/032 may trigger
this).
Link: https://lore.kernel.org/r/9a54f8a696ff17c057cd571be3d15ac3ec1407f1.1589086800.git.riteshh@linux.ibm.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r-- | fs/ext4/mballoc.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 3555e72f149c..c713d06e70b7 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -493,6 +493,8 @@ static void mb_mark_used_double(struct ext4_buddy *e4b, int first, int count) static void mb_cmp_bitmaps(struct ext4_buddy *e4b, void *bitmap) { + if (unlikely(e4b->bd_info->bb_bitmap == NULL)) + return; if (memcmp(e4b->bd_info->bb_bitmap, bitmap, e4b->bd_sb->s_blocksize)) { unsigned char *b1, *b2; int i; @@ -517,10 +519,15 @@ static void mb_group_bb_bitmap_alloc(struct super_block *sb, struct buffer_head *bh; grp->bb_bitmap = kmalloc(sb->s_blocksize, GFP_NOFS); - BUG_ON(grp->bb_bitmap == NULL); + if (!grp->bb_bitmap) + return; bh = ext4_read_block_bitmap(sb, group); - BUG_ON(IS_ERR_OR_NULL(bh)); + if (IS_ERR_OR_NULL(bh)) { + kfree(grp->bb_bitmap); + grp->bb_bitmap = NULL; + return; + } memcpy(grp->bb_bitmap, bh->b_data, sb->s_blocksize); put_bh(bh); |