From 6141b30dba649c3da2acacaa20895b2fe6ac3a2b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 8 Sep 2022 19:10:54 +0200 Subject: [PATCH] 5.15-stable patches added patches: efi-capsule-loader-fix-use-after-free-in-efi_capsule_write.patch efi-libstub-disable-struct-randomization.patch fs-only-do-a-memory-barrier-for-the-first-set_buffer_uptodate.patch net-mvpp2-debugfs-fix-memory-leak-when-using-debugfs_lookup.patch revert-mm-kmemleak-take-a-full-lowmem-check-in-kmemleak_-_phys.patch wifi-iwlegacy-4965-corrected-fix-for-potential-off-by-one-overflow-in-il4965_rs_fill_link_cmd.patch --- ...-use-after-free-in-efi_capsule_write.patch | 82 +++++++++++++++++ ...libstub-disable-struct-randomization.patch | 51 +++++++++++ ...er-for-the-first-set_buffer_uptodate.patch | 72 +++++++++++++++ ...emory-leak-when-using-debugfs_lookup.patch | 45 ++++++++++ ...full-lowmem-check-in-kmemleak_-_phys.patch | 88 +++++++++++++++++++ queue-5.15/series | 6 ++ ...-overflow-in-il4965_rs_fill_link_cmd.patch | 51 +++++++++++ 7 files changed, 395 insertions(+) create mode 100644 queue-5.15/efi-capsule-loader-fix-use-after-free-in-efi_capsule_write.patch create mode 100644 queue-5.15/efi-libstub-disable-struct-randomization.patch create mode 100644 queue-5.15/fs-only-do-a-memory-barrier-for-the-first-set_buffer_uptodate.patch create mode 100644 queue-5.15/net-mvpp2-debugfs-fix-memory-leak-when-using-debugfs_lookup.patch create mode 100644 queue-5.15/revert-mm-kmemleak-take-a-full-lowmem-check-in-kmemleak_-_phys.patch create mode 100644 queue-5.15/wifi-iwlegacy-4965-corrected-fix-for-potential-off-by-one-overflow-in-il4965_rs_fill_link_cmd.patch diff --git a/queue-5.15/efi-capsule-loader-fix-use-after-free-in-efi_capsule_write.patch b/queue-5.15/efi-capsule-loader-fix-use-after-free-in-efi_capsule_write.patch new file mode 100644 index 00000000000..6e141fd3403 --- /dev/null +++ b/queue-5.15/efi-capsule-loader-fix-use-after-free-in-efi_capsule_write.patch @@ -0,0 +1,82 @@ +From 9cb636b5f6a8cc6d1b50809ec8f8d33ae0c84c95 Mon Sep 17 00:00:00 2001 +From: Hyunwoo Kim +Date: Wed, 7 Sep 2022 09:07:14 -0700 +Subject: efi: capsule-loader: Fix use-after-free in efi_capsule_write + +From: Hyunwoo Kim + +commit 9cb636b5f6a8cc6d1b50809ec8f8d33ae0c84c95 upstream. + +A race condition may occur if the user calls close() on another thread +during a write() operation on the device node of the efi capsule. + +This is a race condition that occurs between the efi_capsule_write() and +efi_capsule_flush() functions of efi_capsule_fops, which ultimately +results in UAF. + +So, the page freeing process is modified to be done in +efi_capsule_release() instead of efi_capsule_flush(). + +Cc: # v4.9+ +Signed-off-by: Hyunwoo Kim +Link: https://lore.kernel.org/all/20220907102920.GA88602@ubuntu/ +Signed-off-by: Ard Biesheuvel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firmware/efi/capsule-loader.c | 31 +++++++------------------------ + 1 file changed, 7 insertions(+), 24 deletions(-) + +--- a/drivers/firmware/efi/capsule-loader.c ++++ b/drivers/firmware/efi/capsule-loader.c +@@ -243,29 +243,6 @@ failed: + } + + /** +- * efi_capsule_flush - called by file close or file flush +- * @file: file pointer +- * @id: not used +- * +- * If a capsule is being partially uploaded then calling this function +- * will be treated as upload termination and will free those completed +- * buffer pages and -ECANCELED will be returned. +- **/ +-static int efi_capsule_flush(struct file *file, fl_owner_t id) +-{ +- int ret = 0; +- struct capsule_info *cap_info = file->private_data; +- +- if (cap_info->index > 0) { +- pr_err("capsule upload not complete\n"); +- efi_free_all_buff_pages(cap_info); +- ret = -ECANCELED; +- } +- +- return ret; +-} +- +-/** + * efi_capsule_release - called by file close + * @inode: not used + * @file: file pointer +@@ -277,6 +254,13 @@ static int efi_capsule_release(struct in + { + struct capsule_info *cap_info = file->private_data; + ++ if (cap_info->index > 0 && ++ (cap_info->header.headersize == 0 || ++ cap_info->count < cap_info->total_size)) { ++ pr_err("capsule upload not complete\n"); ++ efi_free_all_buff_pages(cap_info); ++ } ++ + kfree(cap_info->pages); + kfree(cap_info->phys); + kfree(file->private_data); +@@ -324,7 +308,6 @@ static const struct file_operations efi_ + .owner = THIS_MODULE, + .open = efi_capsule_open, + .write = efi_capsule_write, +- .flush = efi_capsule_flush, + .release = efi_capsule_release, + .llseek = no_llseek, + }; diff --git a/queue-5.15/efi-libstub-disable-struct-randomization.patch b/queue-5.15/efi-libstub-disable-struct-randomization.patch new file mode 100644 index 00000000000..779f7b8a927 --- /dev/null +++ b/queue-5.15/efi-libstub-disable-struct-randomization.patch @@ -0,0 +1,51 @@ +From 1a3887924a7e6edd331be76da7bf4c1e8eab4b1e Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Mon, 22 Aug 2022 19:20:33 +0200 +Subject: efi: libstub: Disable struct randomization + +From: Ard Biesheuvel + +commit 1a3887924a7e6edd331be76da7bf4c1e8eab4b1e upstream. + +The EFI stub is a wrapper around the core kernel that makes it look like +a EFI compatible PE/COFF application to the EFI firmware. EFI +applications run on top of the EFI runtime, which is heavily based on +so-called protocols, which are struct types consisting [mostly] of +function pointer members that are instantiated and recorded in a +protocol database. + +These structs look like the ideal randomization candidates to the +randstruct plugin (as they only carry function pointers), but of course, +these protocols are contracts between the firmware that exposes them, +and the EFI applications (including our stubbed kernel) that invoke +them. This means that struct randomization for EFI protocols is not a +great idea, and given that the stub shares very little data with the +core kernel that is represented as a randomizable struct, we're better +off just disabling it completely here. + +Cc: # v4.14+ +Reported-by: Daniel Marth +Tested-by: Daniel Marth +Signed-off-by: Ard Biesheuvel +Acked-by: Kees Cook +Signed-off-by: Greg Kroah-Hartman +--- + drivers/firmware/efi/libstub/Makefile | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/firmware/efi/libstub/Makefile ++++ b/drivers/firmware/efi/libstub/Makefile +@@ -37,6 +37,13 @@ KBUILD_CFLAGS := $(cflags-y) -Os -DDIS + $(call cc-option,-fno-addrsig) \ + -D__DISABLE_EXPORTS + ++# ++# struct randomization only makes sense for Linux internal types, which the EFI ++# stub code never touches, so let's turn off struct randomization for the stub ++# altogether ++# ++KBUILD_CFLAGS := $(filter-out $(RANDSTRUCT_CFLAGS), $(KBUILD_CFLAGS)) ++ + # remove SCS flags from all objects in this directory + KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS)) + # disable LTO diff --git a/queue-5.15/fs-only-do-a-memory-barrier-for-the-first-set_buffer_uptodate.patch b/queue-5.15/fs-only-do-a-memory-barrier-for-the-first-set_buffer_uptodate.patch new file mode 100644 index 00000000000..f6ed50355a9 --- /dev/null +++ b/queue-5.15/fs-only-do-a-memory-barrier-for-the-first-set_buffer_uptodate.patch @@ -0,0 +1,72 @@ +From 2f79cdfe58c13949bbbb65ba5926abfe9561d0ec Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Wed, 31 Aug 2022 09:46:12 -0700 +Subject: fs: only do a memory barrier for the first set_buffer_uptodate() + +From: Linus Torvalds + +commit 2f79cdfe58c13949bbbb65ba5926abfe9561d0ec upstream. + +Commit d4252071b97d ("add barriers to buffer_uptodate and +set_buffer_uptodate") added proper memory barriers to the buffer head +BH_Uptodate bit, so that anybody who tests a buffer for being up-to-date +will be guaranteed to actually see initialized state. + +However, that commit didn't _just_ add the memory barrier, it also ended +up dropping the "was it already set" logic that the BUFFER_FNS() macro +had. + +That's conceptually the right thing for a generic "this is a memory +barrier" operation, but in the case of the buffer contents, we really +only care about the memory barrier for the _first_ time we set the bit, +in that the only memory ordering protection we need is to avoid anybody +seeing uninitialized memory contents. + +Any other access ordering wouldn't be about the BH_Uptodate bit anyway, +and would require some other proper lock (typically BH_Lock or the folio +lock). A reader that races with somebody invalidating the buffer head +isn't an issue wrt the memory ordering, it's a serialization issue. + +Now, you'd think that the buffer head operations don't matter in this +day and age (and I certainly thought so), but apparently some loads +still end up being heavy users of buffer heads. In particular, the +kernel test robot reported that not having this bit access optimization +in place caused a noticeable direct IO performance regression on ext4: + + fxmark.ssd_ext4_no_jnl_DWTL_54_directio.works/sec -26.5% regression + +although you presumably need a fast disk and a lot of cores to actually +notice. + +Link: https://lore.kernel.org/all/Yw8L7HTZ%2FdE2%2Fo9C@xsang-OptiPlex-9020/ +Reported-by: kernel test robot +Tested-by: Fengwei Yin +Cc: Mikulas Patocka +Cc: Matthew Wilcox (Oracle) +Cc: stable@kernel.org +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/buffer_head.h | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/include/linux/buffer_head.h ++++ b/include/linux/buffer_head.h +@@ -137,6 +137,17 @@ BUFFER_FNS(Defer_Completion, defer_compl + static __always_inline void set_buffer_uptodate(struct buffer_head *bh) + { + /* ++ * If somebody else already set this uptodate, they will ++ * have done the memory barrier, and a reader will thus ++ * see *some* valid buffer state. ++ * ++ * Any other serialization (with IO errors or whatever that ++ * might clear the bit) has to come from other state (eg BH_Lock). ++ */ ++ if (test_bit(BH_Uptodate, &bh->b_state)) ++ return; ++ ++ /* + * make it consistent with folio_mark_uptodate + * pairs with smp_load_acquire in buffer_uptodate + */ diff --git a/queue-5.15/net-mvpp2-debugfs-fix-memory-leak-when-using-debugfs_lookup.patch b/queue-5.15/net-mvpp2-debugfs-fix-memory-leak-when-using-debugfs_lookup.patch new file mode 100644 index 00000000000..b1944196804 --- /dev/null +++ b/queue-5.15/net-mvpp2-debugfs-fix-memory-leak-when-using-debugfs_lookup.patch @@ -0,0 +1,45 @@ +From fe2c9c61f668cde28dac2b188028c5299cedcc1e Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Fri, 2 Sep 2022 15:41:11 +0200 +Subject: net: mvpp2: debugfs: fix memory leak when using debugfs_lookup() + +From: Greg Kroah-Hartman + +commit fe2c9c61f668cde28dac2b188028c5299cedcc1e upstream. + +When calling debugfs_lookup() the result must have dput() called on it, +otherwise the memory will leak over time. Fix this up to be much +simpler logic and only create the root debugfs directory once when the +driver is first accessed. That resolves the memory leak and makes +things more obvious as to what the intent is. + +Cc: Marcin Wojtas +Cc: Russell King +Cc: "David S. Miller" +Cc: Eric Dumazet +Cc: Jakub Kicinski +Cc: Paolo Abeni +Cc: netdev@vger.kernel.org +Cc: stable +Fixes: 21da57a23125 ("net: mvpp2: add a debugfs interface for the Header Parser") +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c ++++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_debugfs.c +@@ -700,10 +700,10 @@ void mvpp2_dbgfs_cleanup(struct mvpp2 *p + + void mvpp2_dbgfs_init(struct mvpp2 *priv, const char *name) + { +- struct dentry *mvpp2_dir, *mvpp2_root; ++ static struct dentry *mvpp2_root; ++ struct dentry *mvpp2_dir; + int ret, i; + +- mvpp2_root = debugfs_lookup(MVPP2_DRIVER_NAME, NULL); + if (!mvpp2_root) + mvpp2_root = debugfs_create_dir(MVPP2_DRIVER_NAME, NULL); + diff --git a/queue-5.15/revert-mm-kmemleak-take-a-full-lowmem-check-in-kmemleak_-_phys.patch b/queue-5.15/revert-mm-kmemleak-take-a-full-lowmem-check-in-kmemleak_-_phys.patch new file mode 100644 index 00000000000..bf11132634a --- /dev/null +++ b/queue-5.15/revert-mm-kmemleak-take-a-full-lowmem-check-in-kmemleak_-_phys.patch @@ -0,0 +1,88 @@ +From yee.lee@mediatek.com Thu Sep 8 19:05:17 2022 +From: +Date: Tue, 6 Sep 2022 15:03:06 +0800 +Subject: Revert "mm: kmemleak: take a full lowmem check in kmemleak_*_phys()" +To: +Cc: , Yee Lee , , Catalin Marinas , "Andrew Morton" , Matthias Brugger , "open list:MEMORY MANAGEMENT" , "moderated list:ARM/Mediatek SoC support" , "moderated list:ARM/Mediatek SoC support" +Message-ID: <20220906070309.18809-1-yee.lee@mediatek.com> + +From: Yee Lee + +This reverts commit 23c2d497de21f25898fbea70aeb292ab8acc8c94. + +Commit 23c2d497de21 ("mm: kmemleak: take a full lowmem check in +kmemleak_*_phys()") brought false leak alarms on some archs like arm64 +that does not init pfn boundary in early booting. The final solution +lands on linux-6.0: commit 0c24e061196c ("mm: kmemleak: add rbtree and +store physical address for objects allocated with PA"). + +Revert this commit before linux-6.0. The original issue of invalid PA +can be mitigated by additional check in devicetree. + +The false alarm report is as following: Kmemleak output: (Qemu/arm64) +unreferenced object 0xffff0000c0170a00 (size 128): + comm "swapper/0", pid 1, jiffies 4294892404 (age 126.208s) + hex dump (first 32 bytes): + 62 61 73 65 00 00 00 00 00 00 00 00 00 00 00 00 base............ + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [<(____ptrval____)>] __kmalloc_track_caller+0x1b0/0x2e4 + [<(____ptrval____)>] kstrdup_const+0x8c/0xc4 + [<(____ptrval____)>] kvasprintf_const+0xbc/0xec + [<(____ptrval____)>] kobject_set_name_vargs+0x58/0xe4 + [<(____ptrval____)>] kobject_add+0x84/0x100 + [<(____ptrval____)>] __of_attach_node_sysfs+0x78/0xec + [<(____ptrval____)>] of_core_init+0x68/0x104 + [<(____ptrval____)>] driver_init+0x28/0x48 + [<(____ptrval____)>] do_basic_setup+0x14/0x28 + [<(____ptrval____)>] kernel_init_freeable+0x110/0x178 + [<(____ptrval____)>] kernel_init+0x20/0x1a0 + [<(____ptrval____)>] ret_from_fork+0x10/0x20 + +This pacth is also applicable to linux-5.17.y/linux-5.18.y/linux-5.19.y + +Cc: +Signed-off-by: Yee Lee +Signed-off-by: Greg Kroah-Hartman +--- + mm/kmemleak.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/mm/kmemleak.c ++++ b/mm/kmemleak.c +@@ -1125,7 +1125,7 @@ EXPORT_SYMBOL(kmemleak_no_scan); + void __ref kmemleak_alloc_phys(phys_addr_t phys, size_t size, int min_count, + gfp_t gfp) + { +- if (PHYS_PFN(phys) >= min_low_pfn && PHYS_PFN(phys) < max_low_pfn) ++ if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn) + kmemleak_alloc(__va(phys), size, min_count, gfp); + } + EXPORT_SYMBOL(kmemleak_alloc_phys); +@@ -1139,7 +1139,7 @@ EXPORT_SYMBOL(kmemleak_alloc_phys); + */ + void __ref kmemleak_free_part_phys(phys_addr_t phys, size_t size) + { +- if (PHYS_PFN(phys) >= min_low_pfn && PHYS_PFN(phys) < max_low_pfn) ++ if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn) + kmemleak_free_part(__va(phys), size); + } + EXPORT_SYMBOL(kmemleak_free_part_phys); +@@ -1151,7 +1151,7 @@ EXPORT_SYMBOL(kmemleak_free_part_phys); + */ + void __ref kmemleak_not_leak_phys(phys_addr_t phys) + { +- if (PHYS_PFN(phys) >= min_low_pfn && PHYS_PFN(phys) < max_low_pfn) ++ if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn) + kmemleak_not_leak(__va(phys)); + } + EXPORT_SYMBOL(kmemleak_not_leak_phys); +@@ -1163,7 +1163,7 @@ EXPORT_SYMBOL(kmemleak_not_leak_phys); + */ + void __ref kmemleak_ignore_phys(phys_addr_t phys) + { +- if (PHYS_PFN(phys) >= min_low_pfn && PHYS_PFN(phys) < max_low_pfn) ++ if (!IS_ENABLED(CONFIG_HIGHMEM) || PHYS_PFN(phys) < max_low_pfn) + kmemleak_ignore(__va(phys)); + } + EXPORT_SYMBOL(kmemleak_ignore_phys); diff --git a/queue-5.15/series b/queue-5.15/series index 1ab8cadc934..754f66d8b11 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -1 +1,7 @@ net-wwan-iosm-remove-pointless-null-check.patch +efi-libstub-disable-struct-randomization.patch +efi-capsule-loader-fix-use-after-free-in-efi_capsule_write.patch +wifi-iwlegacy-4965-corrected-fix-for-potential-off-by-one-overflow-in-il4965_rs_fill_link_cmd.patch +net-mvpp2-debugfs-fix-memory-leak-when-using-debugfs_lookup.patch +fs-only-do-a-memory-barrier-for-the-first-set_buffer_uptodate.patch +revert-mm-kmemleak-take-a-full-lowmem-check-in-kmemleak_-_phys.patch diff --git a/queue-5.15/wifi-iwlegacy-4965-corrected-fix-for-potential-off-by-one-overflow-in-il4965_rs_fill_link_cmd.patch b/queue-5.15/wifi-iwlegacy-4965-corrected-fix-for-potential-off-by-one-overflow-in-il4965_rs_fill_link_cmd.patch new file mode 100644 index 00000000000..36da6bd40c0 --- /dev/null +++ b/queue-5.15/wifi-iwlegacy-4965-corrected-fix-for-potential-off-by-one-overflow-in-il4965_rs_fill_link_cmd.patch @@ -0,0 +1,51 @@ +From 6d0ef7241553f3553a0a2764c69b07892705924c Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Mon, 15 Aug 2022 09:37:37 +0200 +Subject: wifi: iwlegacy: 4965: corrected fix for potential off-by-one overflow in il4965_rs_fill_link_cmd() + +From: Stanislaw Gruszka + +commit 6d0ef7241553f3553a0a2764c69b07892705924c upstream. + +This reverts commit a8eb8e6f7159c7c20c0ddac428bde3d110890aa7 as +it can cause invalid link quality command sent to the firmware +and address the off-by-one issue by fixing condition of while loop. + +Cc: stable@vger.kernel.org +Fixes: a8eb8e6f7159 ("wifi: iwlegacy: 4965: fix potential off-by-one overflow in il4965_rs_fill_link_cmd()") +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20220815073737.GA999388@wp.pl +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/intel/iwlegacy/4965-rs.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/drivers/net/wireless/intel/iwlegacy/4965-rs.c ++++ b/drivers/net/wireless/intel/iwlegacy/4965-rs.c +@@ -2403,7 +2403,7 @@ il4965_rs_fill_link_cmd(struct il_priv * + /* Repeat initial/next rate. + * For legacy IL_NUMBER_TRY == 1, this loop will not execute. + * For HT IL_HT_NUMBER_TRY == 3, this executes twice. */ +- while (repeat_rate > 0) { ++ while (repeat_rate > 0 && idx < (LINK_QUAL_MAX_RETRY_NUM - 1)) { + if (is_legacy(tbl_type.lq_type)) { + if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) + ant_toggle_cnt++; +@@ -2422,8 +2422,6 @@ il4965_rs_fill_link_cmd(struct il_priv * + cpu_to_le32(new_rate); + repeat_rate--; + idx++; +- if (idx >= LINK_QUAL_MAX_RETRY_NUM) +- goto out; + } + + il4965_rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, +@@ -2468,7 +2466,6 @@ il4965_rs_fill_link_cmd(struct il_priv * + repeat_rate--; + } + +-out: + lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF; + lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF; + -- 2.47.3