]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
udf: Avoid using corrupted block bitmap buffer
authorJan Kara <jack@suse.cz>
Mon, 17 Jun 2024 15:41:52 +0000 (17:41 +0200)
committerJan Kara <jack@suse.cz>
Wed, 26 Jun 2024 10:54:08 +0000 (12:54 +0200)
When the filesystem block bitmap is corrupted, we detect the corruption
while loading the bitmap and fail the allocation with error. However the
next allocation from the same bitmap will notice the bitmap buffer is
already loaded and tries to allocate from the bitmap with mixed results
(depending on the exact nature of the bitmap corruption). Fix the
problem by using BH_verified bit to indicate whether the bitmap is valid
or not.

Reported-by: syzbot+5f682cd029581f9edfd1@syzkaller.appspotmail.com
CC: stable@vger.kernel.org
Link: https://patch.msgid.link/20240617154201.29512-2-jack@suse.cz
Fixes: 1e0d4adf17e7 ("udf: Check consistency of Space Bitmap Descriptor")
Signed-off-by: Jan Kara <jack@suse.cz>
fs/udf/balloc.c
fs/udf/super.c

index ab3ffc355949dcd52bc377ec27e13335484ba16e..558ad046972ad53c7a48a69c51f46e03869e3411 100644 (file)
@@ -64,8 +64,12 @@ static int read_block_bitmap(struct super_block *sb,
        }
 
        for (i = 0; i < count; i++)
-               if (udf_test_bit(i + off, bh->b_data))
+               if (udf_test_bit(i + off, bh->b_data)) {
+                       bitmap->s_block_bitmap[bitmap_nr] =
+                                                       ERR_PTR(-EFSCORRUPTED);
+                       brelse(bh);
                        return -EFSCORRUPTED;
+               }
        return 0;
 }
 
@@ -81,8 +85,15 @@ static int __load_block_bitmap(struct super_block *sb,
                          block_group, nr_groups);
        }
 
-       if (bitmap->s_block_bitmap[block_group])
+       if (bitmap->s_block_bitmap[block_group]) {
+               /*
+                * The bitmap failed verification in the past. No point in
+                * trying again.
+                */
+               if (IS_ERR(bitmap->s_block_bitmap[block_group]))
+                       return PTR_ERR(bitmap->s_block_bitmap[block_group]);
                return block_group;
+       }
 
        retval = read_block_bitmap(sb, bitmap, block_group, block_group);
        if (retval < 0)
index 9381a66c6ce589d811dd108ade8fad82d3605831..92d47705390563ab83fc9921d6514878cf61b4fe 100644 (file)
@@ -336,7 +336,8 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
        int nr_groups = bitmap->s_nr_groups;
 
        for (i = 0; i < nr_groups; i++)
-               brelse(bitmap->s_block_bitmap[i]);
+               if (!IS_ERR_OR_NULL(bitmap->s_block_bitmap[i]))
+                       brelse(bitmap->s_block_bitmap[i]);
 
        kvfree(bitmap);
 }