diff options
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-52622.patch')
-rw-r--r-- | meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-52622.patch | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-52622.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-52622.patch new file mode 100644 index 000000000..9f16384b9 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/CVE-2023-52622.patch @@ -0,0 +1,131 @@ +From b183fe8702e78bba3dcef8e7193cab6898abee07 Mon Sep 17 00:00:00 2001 +From: Baokun Li <libaokun1@huawei.com> +Date: Mon, 23 Oct 2023 09:30:56 +0800 +Subject: ext4: avoid online resizing failures due to oversized flex bg +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +[ Upstream commit 5d1935ac02ca5aee364a449a35e2977ea84509b0 ] + +When we online resize an ext4 filesystem with a oversized flexbg_size, + + mkfs.ext4 -F -G 67108864 $dev -b 4096 100M + mount $dev $dir + resize2fs $dev 16G + +the following WARN_ON is triggered: +================================================================== +WARNING: CPU: 0 PID: 427 at mm/page_alloc.c:4402 __alloc_pages+0x411/0x550 +Modules linked in: sg(E) +CPU: 0 PID: 427 Comm: resize2fs Tainted: G E 6.6.0-rc5+ #314 +RIP: 0010:__alloc_pages+0x411/0x550 +Call Trace: + <TASK> + __kmalloc_large_node+0xa2/0x200 + __kmalloc+0x16e/0x290 + ext4_resize_fs+0x481/0xd80 + __ext4_ioctl+0x1616/0x1d90 + ext4_ioctl+0x12/0x20 + __x64_sys_ioctl+0xf0/0x150 + do_syscall_64+0x3b/0x90 +================================================================== + +This is because flexbg_size is too large and the size of the new_group_data +array to be allocated exceeds MAX_ORDER. Currently, the minimum value of +MAX_ORDER is 8, the minimum value of PAGE_SIZE is 4096, the corresponding +maximum number of groups that can be allocated is: + + (PAGE_SIZE << MAX_ORDER) / sizeof(struct ext4_new_group_data) ≈ 21845 + +And the value that is down-aligned to the power of 2 is 16384. Therefore, +this value is defined as MAX_RESIZE_BG, and the number of groups added +each time does not exceed this value during resizing, and is added multiple +times to complete the online resizing. The difference is that the metadata +in a flex_bg may be more dispersed. + +Signed-off-by: Baokun Li <libaokun1@huawei.com> +Reviewed-by: Jan Kara <jack@suse.cz> +Link: https://lore.kernel.org/r/20231023013057.2117948-4-libaokun1@huawei.com +Signed-off-by: Theodore Ts'o <tytso@mit.edu> +Signed-off-by: Sasha Levin <sashal@kernel.org> +--- + fs/ext4/resize.c | 25 +++++++++++++++++-------- + 1 file changed, 17 insertions(+), 8 deletions(-) + +diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c +index b63cb88ccdae..355acc064a14 100644 +--- a/fs/ext4/resize.c ++++ b/fs/ext4/resize.c +@@ -217,10 +217,16 @@ struct ext4_new_flex_group_data { + in the flex group */ + __u16 *bg_flags; /* block group flags of groups + in @groups */ ++ ext4_group_t resize_bg; /* number of allocated ++ new_group_data */ + ext4_group_t count; /* number of groups in @groups + */ + }; + ++/* ++ * Avoiding memory allocation failures due to too many groups added each time. ++ */ ++#define MAX_RESIZE_BG 16384 + /* + * alloc_flex_gd() allocates a ext4_new_flex_group_data with size of + * @flexbg_size. +@@ -237,15 +243,18 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned long flexbg_size) + + if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_group_data)) + goto out2; +- flex_gd->count = flexbg_size; ++ if (unlikely(flexbg_size > MAX_RESIZE_BG)) ++ flex_gd->resize_bg = MAX_RESIZE_BG; ++ else ++ flex_gd->resize_bg = flexbg_size; + +- flex_gd->groups = kmalloc_array(flexbg_size, +- sizeof(struct ext4_new_group_data), +- GFP_NOFS); ++ flex_gd->groups = kmalloc_array(flex_gd->resize_bg, ++ sizeof(struct ext4_new_group_data), ++ GFP_NOFS); + if (flex_gd->groups == NULL) + goto out2; + +- flex_gd->bg_flags = kmalloc_array(flexbg_size, sizeof(__u16), ++ flex_gd->bg_flags = kmalloc_array(flex_gd->resize_bg, sizeof(__u16), + GFP_NOFS); + if (flex_gd->bg_flags == NULL) + goto out1; +@@ -1566,8 +1575,7 @@ static int ext4_flex_group_add(struct super_block *sb, + + static int ext4_setup_next_flex_gd(struct super_block *sb, + struct ext4_new_flex_group_data *flex_gd, +- ext4_fsblk_t n_blocks_count, +- unsigned long flexbg_size) ++ ext4_fsblk_t n_blocks_count) + { + struct ext4_sb_info *sbi = EXT4_SB(sb); + struct ext4_super_block *es = sbi->s_es; +@@ -1591,7 +1599,7 @@ static int ext4_setup_next_flex_gd(struct super_block *sb, + BUG_ON(last); + ext4_get_group_no_and_offset(sb, n_blocks_count - 1, &n_group, &last); + +- last_group = group | (flexbg_size - 1); ++ last_group = group | (flex_gd->resize_bg - 1); + if (last_group > n_group) + last_group = n_group; + +@@ -2087,8 +2095,7 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count) + /* Add flex groups. Note that a regular group is a + * flex group with 1 group. + */ +- while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count, +- flexbg_size)) { ++ while (ext4_setup_next_flex_gd(sb, flex_gd, n_blocks_count)) { + if (jiffies - last_update_time > HZ * 10) { + if (last_update_time) + ext4_msg(sb, KERN_INFO, +cgit 1.2.3-korg + |