Skip to content

Commit a90d447

Browse files
committed
udf: Avoid using corrupted block bitmap buffer
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: [email protected] CC: [email protected] Link: https://patch.msgid.link/[email protected] Fixes: 1e0d4ad ("udf: Check consistency of Space Bitmap Descriptor") Signed-off-by: Jan Kara <[email protected]>
1 parent 27ab338 commit a90d447

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

fs/udf/balloc.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,12 @@ static int read_block_bitmap(struct super_block *sb,
6464
}
6565

6666
for (i = 0; i < count; i++)
67-
if (udf_test_bit(i + off, bh->b_data))
67+
if (udf_test_bit(i + off, bh->b_data)) {
68+
bitmap->s_block_bitmap[bitmap_nr] =
69+
ERR_PTR(-EFSCORRUPTED);
70+
brelse(bh);
6871
return -EFSCORRUPTED;
72+
}
6973
return 0;
7074
}
7175

@@ -81,8 +85,15 @@ static int __load_block_bitmap(struct super_block *sb,
8185
block_group, nr_groups);
8286
}
8387

84-
if (bitmap->s_block_bitmap[block_group])
88+
if (bitmap->s_block_bitmap[block_group]) {
89+
/*
90+
* The bitmap failed verification in the past. No point in
91+
* trying again.
92+
*/
93+
if (IS_ERR(bitmap->s_block_bitmap[block_group]))
94+
return PTR_ERR(bitmap->s_block_bitmap[block_group]);
8595
return block_group;
96+
}
8697

8798
retval = read_block_bitmap(sb, bitmap, block_group, block_group);
8899
if (retval < 0)

fs/udf/super.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,8 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
336336
int nr_groups = bitmap->s_nr_groups;
337337

338338
for (i = 0; i < nr_groups; i++)
339-
brelse(bitmap->s_block_bitmap[i]);
339+
if (!IS_ERR_OR_NULL(bitmap->s_block_bitmap[i]))
340+
brelse(bitmap->s_block_bitmap[i]);
340341

341342
kvfree(bitmap);
342343
}

0 commit comments

Comments
 (0)