Commit d6e3b870 authored by Jan Kara's avatar Jan Kara Committed by Ye Bin
Browse files

udf: Avoid using corrupted block bitmap buffer

stable inclusion
from stable-v5.10.224
commit 2199e157a465aaf98294d3932797ecd7fce942d5
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAKPZN
CVE: CVE-2024-42306

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2199e157a465aaf98294d3932797ecd7fce942d5



--------------------------------

commit a90d4471146de21745980cba51ce88e7926bcc4f upstream.

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: default avatar <syzbot+5f682cd029581f9edfd1@syzkaller.appspotmail.com>
CC: stable@vger.kernel.org
Link: https://patch.msgid.link/20240617154201.29512-2-jack@suse.cz


Fixes: 1e0d4adf ("udf: Check consistency of Space Bitmap Descriptor")
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarYe Bin <yebin10@huawei.com>
parent 5184a907
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -68,8 +68,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;
}

@@ -85,8 +89,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)
+2 −1
Original line number Diff line number Diff line
@@ -266,6 +266,7 @@ static void udf_sb_free_bitmap(struct udf_bitmap *bitmap)
	int nr_groups = bitmap->s_nr_groups;

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

	kvfree(bitmap);