From: Greg Kroah-Hartman Date: Wed, 7 Jun 2023 12:32:31 +0000 (+0200) Subject: 5.4-stable patches X-Git-Tag: v4.14.317~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2db44f1b592ff654f48781627a09cbe4e1d1ae98;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: ext4-add-ea_inode-checking-to-ext4_iget.patch ext4-add-lockdep-annotations-for-i_data_sem-for-ea_inode-s.patch ext4-disallow-ea_inodes-with-extended-attributes.patch ext4-set-lockdep-subclass-for-the-ea_inode-in-ext4_xattr_inode_cache_find.patch fbcon-fix-null-ptr-deref-in-soft_cursor.patch selinux-don-t-use-make-s-grouped-targets-feature-yet.patch test_firmware-fix-the-memory-leak-of-the-allocated-firmware-buffer.patch tracing-probe-trace_probe_primary_from_call-checked-list_first_entry.patch --- diff --git a/queue-5.4/ext4-add-ea_inode-checking-to-ext4_iget.patch b/queue-5.4/ext4-add-ea_inode-checking-to-ext4_iget.patch new file mode 100644 index 00000000000..62865051c5c --- /dev/null +++ b/queue-5.4/ext4-add-ea_inode-checking-to-ext4_iget.patch @@ -0,0 +1,180 @@ +From b3e6bcb94590dea45396b9481e47b809b1be4afa Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Tue, 23 May 2023 23:49:48 -0400 +Subject: ext4: add EA_INODE checking to ext4_iget() + +From: Theodore Ts'o + +commit b3e6bcb94590dea45396b9481e47b809b1be4afa upstream. + +Add a new flag, EXT4_IGET_EA_INODE which indicates whether the inode +is expected to have the EA_INODE flag or not. If the flag is not +set/clear as expected, then fail the iget() operation and mark the +file system as corrupted. + +This commit also makes the ext4_iget() always perform the +is_bad_inode() check even when the inode is already inode cache. This +allows us to remove the is_bad_inode() check from the callers of +ext4_iget() in the ea_inode code. + +Reported-by: syzbot+cbb68193bdb95af4340a@syzkaller.appspotmail.com +Reported-by: syzbot+62120febbd1ee3c3c860@syzkaller.appspotmail.com +Reported-by: syzbot+edce54daffee36421b4c@syzkaller.appspotmail.com +Cc: stable@kernel.org +Signed-off-by: Theodore Ts'o +Link: https://lore.kernel.org/r/20230524034951.779531-2-tytso@mit.edu +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/ext4.h | 3 ++- + fs/ext4/inode.c | 31 ++++++++++++++++++++++++++----- + fs/ext4/xattr.c | 36 +++++++----------------------------- + 3 files changed, 35 insertions(+), 35 deletions(-) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -2609,7 +2609,8 @@ typedef enum { + EXT4_IGET_NORMAL = 0, + EXT4_IGET_SPECIAL = 0x0001, /* OK to iget a system inode */ + EXT4_IGET_HANDLE = 0x0002, /* Inode # is from a handle */ +- EXT4_IGET_BAD = 0x0004 /* Allow to iget a bad inode */ ++ EXT4_IGET_BAD = 0x0004, /* Allow to iget a bad inode */ ++ EXT4_IGET_EA_INODE = 0x0008 /* Inode should contain an EA value */ + } ext4_iget_flags; + + extern struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4903,6 +4903,21 @@ static inline u64 ext4_inode_peek_iversi + return inode_peek_iversion(inode); + } + ++static const char *check_igot_inode(struct inode *inode, ext4_iget_flags flags) ++ ++{ ++ if (flags & EXT4_IGET_EA_INODE) { ++ if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) ++ return "missing EA_INODE flag"; ++ } else { ++ if ((EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) ++ return "unexpected EA_INODE flag"; ++ } ++ if (is_bad_inode(inode) && !(flags & EXT4_IGET_BAD)) ++ return "unexpected bad inode w/o EXT4_IGET_BAD"; ++ return NULL; ++} ++ + struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, + ext4_iget_flags flags, const char *function, + unsigned int line) +@@ -4911,6 +4926,7 @@ struct inode *__ext4_iget(struct super_b + struct ext4_inode *raw_inode; + struct ext4_inode_info *ei; + struct inode *inode; ++ const char *err_str; + journal_t *journal = EXT4_SB(sb)->s_journal; + long ret; + loff_t size; +@@ -4934,8 +4950,14 @@ struct inode *__ext4_iget(struct super_b + inode = iget_locked(sb, ino); + if (!inode) + return ERR_PTR(-ENOMEM); +- if (!(inode->i_state & I_NEW)) ++ if (!(inode->i_state & I_NEW)) { ++ if ((err_str = check_igot_inode(inode, flags)) != NULL) { ++ ext4_error_inode(inode, function, line, 0, err_str); ++ iput(inode); ++ return ERR_PTR(-EFSCORRUPTED); ++ } + return inode; ++ } + + ei = EXT4_I(inode); + iloc.bh = NULL; +@@ -5200,10 +5222,9 @@ struct inode *__ext4_iget(struct super_b + if (IS_CASEFOLDED(inode) && !ext4_has_feature_casefold(inode->i_sb)) + ext4_error_inode(inode, function, line, 0, + "casefold flag without casefold feature"); +- if (is_bad_inode(inode) && !(flags & EXT4_IGET_BAD)) { +- ext4_error_inode(inode, function, line, 0, +- "bad inode without EXT4_IGET_BAD flag"); +- ret = -EUCLEAN; ++ if ((err_str = check_igot_inode(inode, flags)) != NULL) { ++ ext4_error_inode(inode, function, line, 0, err_str); ++ ret = -EFSCORRUPTED; + goto bad_inode; + } + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -395,7 +395,7 @@ static int ext4_xattr_inode_iget(struct + return -EFSCORRUPTED; + } + +- inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_NORMAL); ++ inode = ext4_iget(parent->i_sb, ea_ino, EXT4_IGET_EA_INODE); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + ext4_error(parent->i_sb, +@@ -403,23 +403,6 @@ static int ext4_xattr_inode_iget(struct + err); + return err; + } +- +- if (is_bad_inode(inode)) { +- ext4_error(parent->i_sb, +- "error while reading EA inode %lu is_bad_inode", +- ea_ino); +- err = -EIO; +- goto error; +- } +- +- if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) { +- ext4_error(parent->i_sb, +- "EA inode %lu does not have EXT4_EA_INODE_FL flag", +- ea_ino); +- err = -EINVAL; +- goto error; +- } +- + ext4_xattr_inode_set_class(inode); + + /* +@@ -440,9 +423,6 @@ static int ext4_xattr_inode_iget(struct + + *ea_inode = inode; + return 0; +-error: +- iput(inode); +- return err; + } + + /* Remove entry from mbcache when EA inode is getting evicted */ +@@ -1517,11 +1497,10 @@ ext4_xattr_inode_cache_find(struct inode + + while (ce) { + ea_inode = ext4_iget(inode->i_sb, ce->e_value, +- EXT4_IGET_NORMAL); +- if (!IS_ERR(ea_inode) && +- !is_bad_inode(ea_inode) && +- (EXT4_I(ea_inode)->i_flags & EXT4_EA_INODE_FL) && +- i_size_read(ea_inode) == value_len && ++ EXT4_IGET_EA_INODE); ++ if (IS_ERR(ea_inode)) ++ goto next_entry; ++ if (i_size_read(ea_inode) == value_len && + !ext4_xattr_inode_read(ea_inode, ea_data, value_len) && + !ext4_xattr_inode_verify_hashes(ea_inode, NULL, ea_data, + value_len) && +@@ -1531,9 +1510,8 @@ ext4_xattr_inode_cache_find(struct inode + kvfree(ea_data); + return ea_inode; + } +- +- if (!IS_ERR(ea_inode)) +- iput(ea_inode); ++ iput(ea_inode); ++ next_entry: + ce = mb_cache_entry_find_next(ea_inode_cache, ce); + } + kvfree(ea_data); diff --git a/queue-5.4/ext4-add-lockdep-annotations-for-i_data_sem-for-ea_inode-s.patch b/queue-5.4/ext4-add-lockdep-annotations-for-i_data_sem-for-ea_inode-s.patch new file mode 100644 index 00000000000..85c547f56ed --- /dev/null +++ b/queue-5.4/ext4-add-lockdep-annotations-for-i_data_sem-for-ea_inode-s.patch @@ -0,0 +1,57 @@ +From aff3bea95388299eec63440389b4545c8041b357 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Tue, 23 May 2023 23:49:51 -0400 +Subject: ext4: add lockdep annotations for i_data_sem for ea_inode's + +From: Theodore Ts'o + +commit aff3bea95388299eec63440389b4545c8041b357 upstream. + +Treat i_data_sem for ea_inodes as being in their own lockdep class to +avoid lockdep complaints about ext4_setattr's use of inode_lock() on +normal inodes potentially causing lock ordering with i_data_sem on +ea_inodes in ext4_xattr_inode_write(). However, ea_inodes will be +operated on by ext4_setattr(), so this isn't a problem. + +Cc: stable@kernel.org +Link: https://syzkaller.appspot.com/bug?extid=298c5d8fb4a128bc27b0 +Reported-by: syzbot+298c5d8fb4a128bc27b0@syzkaller.appspotmail.com +Signed-off-by: Theodore Ts'o +Link: https://lore.kernel.org/r/20230524034951.779531-5-tytso@mit.edu +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/ext4.h | 2 ++ + fs/ext4/xattr.c | 4 ++++ + 2 files changed, 6 insertions(+) + +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -938,11 +938,13 @@ do { \ + * where the second inode has larger inode number + * than the first + * I_DATA_SEM_QUOTA - Used for quota inodes only ++ * I_DATA_SEM_EA - Used for ea_inodes only + */ + enum { + I_DATA_SEM_NORMAL = 0, + I_DATA_SEM_OTHER, + I_DATA_SEM_QUOTA, ++ I_DATA_SEM_EA + }; + + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -121,7 +121,11 @@ ext4_expand_inode_array(struct ext4_xatt + #ifdef CONFIG_LOCKDEP + void ext4_xattr_inode_set_class(struct inode *ea_inode) + { ++ struct ext4_inode_info *ei = EXT4_I(ea_inode); ++ + lockdep_set_subclass(&ea_inode->i_rwsem, 1); ++ (void) ei; /* shut up clang warning if !CONFIG_LOCKDEP */ ++ lockdep_set_subclass(&ei->i_data_sem, I_DATA_SEM_EA); + } + #endif + diff --git a/queue-5.4/ext4-disallow-ea_inodes-with-extended-attributes.patch b/queue-5.4/ext4-disallow-ea_inodes-with-extended-attributes.patch new file mode 100644 index 00000000000..201645095f6 --- /dev/null +++ b/queue-5.4/ext4-disallow-ea_inodes-with-extended-attributes.patch @@ -0,0 +1,35 @@ +From 2bc7e7c1a3bc9bd0cbf0f71006f6fe7ef24a00c2 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Tue, 23 May 2023 23:49:50 -0400 +Subject: ext4: disallow ea_inodes with extended attributes + +From: Theodore Ts'o + +commit 2bc7e7c1a3bc9bd0cbf0f71006f6fe7ef24a00c2 upstream. + +An ea_inode stores the value of an extended attribute; it can not have +extended attributes itself, or this will cause recursive nightmares. +Add a check in ext4_iget() to make sure this is the case. + +Cc: stable@kernel.org +Reported-by: syzbot+e44749b6ba4d0434cd47@syzkaller.appspotmail.com +Signed-off-by: Theodore Ts'o +Link: https://lore.kernel.org/r/20230524034951.779531-4-tytso@mit.edu +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/inode.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/ext4/inode.c ++++ b/fs/ext4/inode.c +@@ -4909,6 +4909,9 @@ static const char *check_igot_inode(stru + if (flags & EXT4_IGET_EA_INODE) { + if (!(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) + return "missing EA_INODE flag"; ++ if (ext4_test_inode_state(inode, EXT4_STATE_XATTR) || ++ EXT4_I(inode)->i_file_acl) ++ return "ea_inode with extended attributes"; + } else { + if ((EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) + return "unexpected EA_INODE flag"; diff --git a/queue-5.4/ext4-set-lockdep-subclass-for-the-ea_inode-in-ext4_xattr_inode_cache_find.patch b/queue-5.4/ext4-set-lockdep-subclass-for-the-ea_inode-in-ext4_xattr_inode_cache_find.patch new file mode 100644 index 00000000000..627df92294c --- /dev/null +++ b/queue-5.4/ext4-set-lockdep-subclass-for-the-ea_inode-in-ext4_xattr_inode_cache_find.patch @@ -0,0 +1,34 @@ +From b928dfdcb27d8fa59917b794cfba53052a2f050f Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Tue, 23 May 2023 23:49:49 -0400 +Subject: ext4: set lockdep subclass for the ea_inode in ext4_xattr_inode_cache_find() + +From: Theodore Ts'o + +commit b928dfdcb27d8fa59917b794cfba53052a2f050f upstream. + +If the ea_inode has been pushed out of the inode cache while there is +still a reference in the mb_cache, the lockdep subclass will not be +set on the inode, which can lead to some lockdep false positives. + +Fixes: 33d201e0277b ("ext4: fix lockdep warning about recursive inode locking") +Cc: stable@kernel.org +Reported-by: syzbot+d4b971e744b1f5439336@syzkaller.appspotmail.com +Signed-off-by: Theodore Ts'o +Link: https://lore.kernel.org/r/20230524034951.779531-3-tytso@mit.edu +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/xattr.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1500,6 +1500,7 @@ ext4_xattr_inode_cache_find(struct inode + EXT4_IGET_EA_INODE); + if (IS_ERR(ea_inode)) + goto next_entry; ++ ext4_xattr_inode_set_class(ea_inode); + if (i_size_read(ea_inode) == value_len && + !ext4_xattr_inode_read(ea_inode, ea_data, value_len) && + !ext4_xattr_inode_verify_hashes(ea_inode, NULL, ea_data, diff --git a/queue-5.4/fbcon-fix-null-ptr-deref-in-soft_cursor.patch b/queue-5.4/fbcon-fix-null-ptr-deref-in-soft_cursor.patch new file mode 100644 index 00000000000..546e8a614bc --- /dev/null +++ b/queue-5.4/fbcon-fix-null-ptr-deref-in-soft_cursor.patch @@ -0,0 +1,58 @@ +From d78bd6cc68276bd57f766f7cb98bfe32c23ab327 Mon Sep 17 00:00:00 2001 +From: Helge Deller +Date: Sat, 27 May 2023 08:41:09 +0200 +Subject: fbcon: Fix null-ptr-deref in soft_cursor + +From: Helge Deller + +commit d78bd6cc68276bd57f766f7cb98bfe32c23ab327 upstream. + +syzbot repored this bug in the softcursor code: + +BUG: KASAN: null-ptr-deref in soft_cursor+0x384/0x6b4 drivers/video/fbdev/core/softcursor.c:70 +Read of size 16 at addr 0000000000000200 by task kworker/u4:1/12 + +CPU: 0 PID: 12 Comm: kworker/u4:1 Not tainted 6.4.0-rc3-syzkaller-geb0f1697d729 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 04/28/2023 +Workqueue: events_power_efficient fb_flashcursor +Call trace: + dump_backtrace+0x1b8/0x1e4 arch/arm64/kernel/stacktrace.c:233 + show_stack+0x2c/0x44 arch/arm64/kernel/stacktrace.c:240 + __dump_stack lib/dump_stack.c:88 [inline] + dump_stack_lvl+0xd0/0x124 lib/dump_stack.c:106 + print_report+0xe4/0x514 mm/kasan/report.c:465 + kasan_report+0xd4/0x130 mm/kasan/report.c:572 + kasan_check_range+0x264/0x2a4 mm/kasan/generic.c:187 + __asan_memcpy+0x3c/0x84 mm/kasan/shadow.c:105 + soft_cursor+0x384/0x6b4 drivers/video/fbdev/core/softcursor.c:70 + bit_cursor+0x113c/0x1a64 drivers/video/fbdev/core/bitblit.c:377 + fb_flashcursor+0x35c/0x54c drivers/video/fbdev/core/fbcon.c:380 + process_one_work+0x788/0x12d4 kernel/workqueue.c:2405 + worker_thread+0x8e0/0xfe8 kernel/workqueue.c:2552 + kthread+0x288/0x310 kernel/kthread.c:379 + ret_from_fork+0x10/0x20 arch/arm64/kernel/entry.S:853 + +This fix let bit_cursor() bail out early when a font bitmap +isn't available yet. + +Signed-off-by: Helge Deller +Reported-by: syzbot+d910bd780e6efac35869@syzkaller.appspotmail.com +Acked-by: Sam Ravnborg +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/video/fbdev/core/bitblit.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/video/fbdev/core/bitblit.c ++++ b/drivers/video/fbdev/core/bitblit.c +@@ -247,6 +247,9 @@ static void bit_cursor(struct vc_data *v + + cursor.set = 0; + ++ if (!vc->vc_font.data) ++ return; ++ + c = scr_readw((u16 *) vc->vc_pos); + attribute = get_attribute(info, c); + src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height)); diff --git a/queue-5.4/selinux-don-t-use-make-s-grouped-targets-feature-yet.patch b/queue-5.4/selinux-don-t-use-make-s-grouped-targets-feature-yet.patch new file mode 100644 index 00000000000..f435f6b18cc --- /dev/null +++ b/queue-5.4/selinux-don-t-use-make-s-grouped-targets-feature-yet.patch @@ -0,0 +1,42 @@ +From 42c4e97e06a839b07d834f640a10911ad84ec8b3 Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Thu, 1 Jun 2023 10:21:21 -0400 +Subject: selinux: don't use make's grouped targets feature yet + +From: Paul Moore + +commit 42c4e97e06a839b07d834f640a10911ad84ec8b3 upstream. + +The Linux Kernel currently only requires make v3.82 while the grouped +target functionality requires make v4.3. Removed the grouped target +introduced in 4ce1f694eb5d ("selinux: ensure av_permissions.h is +built when needed") as well as the multiple header file targets in +the make rule. This effectively reverts the problem commit. + +We will revisit this change when make >= 4.3 is required by the rest +of the kernel. + +Cc: stable@vger.kernel.org +Fixes: 4ce1f694eb5d ("selinux: ensure av_permissions.h is built when needed") +Reported-by: Erwan Velu +Reported-by: Luiz Capitulino +Tested-by: Luiz Capitulino +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman +--- + security/selinux/Makefile | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/security/selinux/Makefile ++++ b/security/selinux/Makefile +@@ -22,5 +22,9 @@ quiet_cmd_flask = GEN $(obj)/flask.h + cmd_flask = $< $(obj)/flask.h $(obj)/av_permissions.h + + targets += flask.h av_permissions.h +-$(obj)/flask.h $(obj)/av_permissions.h &: scripts/selinux/genheaders/genheaders FORCE ++# once make >= 4.3 is required, we can use grouped targets in the rule below, ++# which basically involves adding both headers and a '&' before the colon, see ++# the example below: ++# $(obj)/flask.h $(obj)/av_permissions.h &: scripts/selinux/... ++$(obj)/flask.h: scripts/selinux/genheaders/genheaders FORCE + $(call if_changed,flask) diff --git a/queue-5.4/series b/queue-5.4/series index c92bfef1f90..dcbc4c27eca 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -81,3 +81,11 @@ lib-dynamic_debug.c-use-address-of-operator-on-section-symbols.patch wifi-rtlwifi-remove-always-true-condition-pointed-out-by-gcc-12.patch mmc-vub300-fix-invalid-response-handling.patch tty-serial-fsl_lpuart-use-uartctrl_txinv-to-send-break-instead-of-uartctrl_sbk.patch +selinux-don-t-use-make-s-grouped-targets-feature-yet.patch +tracing-probe-trace_probe_primary_from_call-checked-list_first_entry.patch +ext4-add-ea_inode-checking-to-ext4_iget.patch +ext4-set-lockdep-subclass-for-the-ea_inode-in-ext4_xattr_inode_cache_find.patch +ext4-disallow-ea_inodes-with-extended-attributes.patch +ext4-add-lockdep-annotations-for-i_data_sem-for-ea_inode-s.patch +fbcon-fix-null-ptr-deref-in-soft_cursor.patch +test_firmware-fix-the-memory-leak-of-the-allocated-firmware-buffer.patch diff --git a/queue-5.4/test_firmware-fix-the-memory-leak-of-the-allocated-firmware-buffer.patch b/queue-5.4/test_firmware-fix-the-memory-leak-of-the-allocated-firmware-buffer.patch new file mode 100644 index 00000000000..9dec02acdb9 --- /dev/null +++ b/queue-5.4/test_firmware-fix-the-memory-leak-of-the-allocated-firmware-buffer.patch @@ -0,0 +1,181 @@ +From 48e156023059e57a8fc68b498439832f7600ffff Mon Sep 17 00:00:00 2001 +From: Mirsad Goran Todorovac +Date: Tue, 9 May 2023 10:47:49 +0200 +Subject: test_firmware: fix the memory leak of the allocated firmware buffer + +From: Mirsad Goran Todorovac + +commit 48e156023059e57a8fc68b498439832f7600ffff upstream. + +The following kernel memory leak was noticed after running +tools/testing/selftests/firmware/fw_run_tests.sh: + +[root@pc-mtodorov firmware]# cat /sys/kernel/debug/kmemleak +. +. +. +unreferenced object 0xffff955389bc3400 (size 1024): + comm "test_firmware-0", pid 5451, jiffies 4294944822 (age 65.652s) + hex dump (first 32 bytes): + 47 48 34 35 36 37 0a 00 00 00 00 00 00 00 00 00 GH4567.......... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] slab_post_alloc_hook+0x8c/0x3c0 + [] __kmem_cache_alloc_node+0x184/0x240 + [] kmalloc_trace+0x2e/0xc0 + [] test_fw_run_batch_request+0x9d/0x180 + [] kthread+0x10b/0x140 + [] ret_from_fork+0x29/0x50 +unreferenced object 0xffff9553c334b400 (size 1024): + comm "test_firmware-1", pid 5452, jiffies 4294944822 (age 65.652s) + hex dump (first 32 bytes): + 47 48 34 35 36 37 0a 00 00 00 00 00 00 00 00 00 GH4567.......... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] slab_post_alloc_hook+0x8c/0x3c0 + [] __kmem_cache_alloc_node+0x184/0x240 + [] kmalloc_trace+0x2e/0xc0 + [] test_fw_run_batch_request+0x9d/0x180 + [] kthread+0x10b/0x140 + [] ret_from_fork+0x29/0x50 +unreferenced object 0xffff9553c334f000 (size 1024): + comm "test_firmware-2", pid 5453, jiffies 4294944822 (age 65.652s) + hex dump (first 32 bytes): + 47 48 34 35 36 37 0a 00 00 00 00 00 00 00 00 00 GH4567.......... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] slab_post_alloc_hook+0x8c/0x3c0 + [] __kmem_cache_alloc_node+0x184/0x240 + [] kmalloc_trace+0x2e/0xc0 + [] test_fw_run_batch_request+0x9d/0x180 + [] kthread+0x10b/0x140 + [] ret_from_fork+0x29/0x50 +unreferenced object 0xffff9553c3348400 (size 1024): + comm "test_firmware-3", pid 5454, jiffies 4294944822 (age 65.652s) + hex dump (first 32 bytes): + 47 48 34 35 36 37 0a 00 00 00 00 00 00 00 00 00 GH4567.......... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + [] slab_post_alloc_hook+0x8c/0x3c0 + [] __kmem_cache_alloc_node+0x184/0x240 + [] kmalloc_trace+0x2e/0xc0 + [] test_fw_run_batch_request+0x9d/0x180 + [] kthread+0x10b/0x140 + [] ret_from_fork+0x29/0x50 +[root@pc-mtodorov firmware]# + +Note that the size 1024 corresponds to the size of the test firmware +buffer. The actual number of the buffers leaked is around 70-110, +depending on the test run. + +The cause of the leak is the following: + +request_partial_firmware_into_buf() and request_firmware_into_buf() +provided firmware buffer isn't released on release_firmware(), we +have allocated it and we are responsible for deallocating it manually. +This is introduced in a number of context where previously only +release_firmware() was called, which was insufficient. + +Reported-by: Mirsad Goran Todorovac +Fixes: 7feebfa487b92 ("test_firmware: add support for request_firmware_into_buf") +Cc: Greg Kroah-Hartman +Cc: Dan Carpenter +Cc: Takashi Iwai +Cc: Luis Chamberlain +Cc: Russ Weight +Cc: Tianfei zhang +Cc: Christophe JAILLET +Cc: Zhengchao Shao +Cc: Colin Ian King +Cc: linux-kernel@vger.kernel.org +Cc: Kees Cook +Cc: Scott Branden +Cc: Luis R. Rodriguez +Cc: linux-kselftest@vger.kernel.org +Cc: stable@vger.kernel.org # v5.4 +Signed-off-by: Mirsad Goran Todorovac +Link: https://lore.kernel.org/r/20230509084746.48259-3-mirsad.todorovac@alu.unizg.hr +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Greg Kroah-Hartman +--- + lib/test_firmware.c | 19 ++++++++++++++++++- + 1 file changed, 18 insertions(+), 1 deletion(-) + +--- a/lib/test_firmware.c ++++ b/lib/test_firmware.c +@@ -38,6 +38,7 @@ struct test_batched_req { + bool sent; + const struct firmware *fw; + const char *name; ++ const char *fw_buf; + struct completion completion; + struct task_struct *task; + struct device *dev; +@@ -134,8 +135,14 @@ static void __test_release_all_firmware( + + for (i = 0; i < test_fw_config->num_requests; i++) { + req = &test_fw_config->reqs[i]; +- if (req->fw) ++ if (req->fw) { ++ if (req->fw_buf) { ++ kfree_const(req->fw_buf); ++ req->fw_buf = NULL; ++ } + release_firmware(req->fw); ++ req->fw = NULL; ++ } + } + + vfree(test_fw_config->reqs); +@@ -489,6 +496,8 @@ static ssize_t trigger_request_store(str + + mutex_lock(&test_fw_mutex); + release_firmware(test_firmware); ++ if (test_fw_config->reqs) ++ __test_release_all_firmware(); + test_firmware = NULL; + rc = request_firmware(&test_firmware, name, dev); + if (rc) { +@@ -531,6 +540,8 @@ static ssize_t trigger_async_request_sto + mutex_lock(&test_fw_mutex); + release_firmware(test_firmware); + test_firmware = NULL; ++ if (test_fw_config->reqs) ++ __test_release_all_firmware(); + rc = request_firmware_nowait(THIS_MODULE, 1, name, dev, GFP_KERNEL, + NULL, trigger_async_request_cb); + if (rc) { +@@ -573,6 +584,8 @@ static ssize_t trigger_custom_fallback_s + + mutex_lock(&test_fw_mutex); + release_firmware(test_firmware); ++ if (test_fw_config->reqs) ++ __test_release_all_firmware(); + test_firmware = NULL; + rc = request_firmware_nowait(THIS_MODULE, FW_ACTION_NOHOTPLUG, name, + dev, GFP_KERNEL, NULL, +@@ -625,6 +638,8 @@ static int test_fw_run_batch_request(voi + TEST_FIRMWARE_BUF_SIZE); + if (!req->fw) + kfree(test_buf); ++ else ++ req->fw_buf = test_buf; + } else { + req->rc = test_fw_config->req_firmware(&req->fw, + req->name, +@@ -680,6 +695,7 @@ static ssize_t trigger_batched_requests_ + req->fw = NULL; + req->idx = i; + req->name = test_fw_config->name; ++ req->fw_buf = NULL; + req->dev = dev; + init_completion(&req->completion); + req->task = kthread_run(test_fw_run_batch_request, req, +@@ -779,6 +795,7 @@ ssize_t trigger_batched_requests_async_s + for (i = 0; i < test_fw_config->num_requests; i++) { + req = &test_fw_config->reqs[i]; + req->name = test_fw_config->name; ++ req->fw_buf = NULL; + req->fw = NULL; + req->idx = i; + init_completion(&req->completion); diff --git a/queue-5.4/tracing-probe-trace_probe_primary_from_call-checked-list_first_entry.patch b/queue-5.4/tracing-probe-trace_probe_primary_from_call-checked-list_first_entry.patch new file mode 100644 index 00000000000..10bdc03336f --- /dev/null +++ b/queue-5.4/tracing-probe-trace_probe_primary_from_call-checked-list_first_entry.patch @@ -0,0 +1,41 @@ +From 81d0fa4cb4fc0e1a49c2b22f92c43d9fe972ebcf Mon Sep 17 00:00:00 2001 +From: Pietro Borrello +Date: Sat, 28 Jan 2023 16:23:41 +0000 +Subject: tracing/probe: trace_probe_primary_from_call(): checked list_first_entry + +From: Pietro Borrello + +commit 81d0fa4cb4fc0e1a49c2b22f92c43d9fe972ebcf upstream. + +All callers of trace_probe_primary_from_call() check the return +value to be non NULL. However, the function returns +list_first_entry(&tpe->probes, ...) which can never be NULL. +Additionally, it does not check for the list being possibly empty, +possibly causing a type confusion on empty lists. +Use list_first_entry_or_null() which solves both problems. + +Link: https://lore.kernel.org/linux-trace-kernel/20230128-list-entry-null-check-v1-1-8bde6a3da2ef@diag.uniroma1.it/ + +Fixes: 60d53e2c3b75 ("tracing/probe: Split trace_event related data from trace_probe") +Signed-off-by: Pietro Borrello +Reviewed-by: Steven Rostedt (Google) +Acked-by: Masami Hiramatsu (Google) +Acked-by: Mukesh Ojha +Cc: stable@vger.kernel.org +Signed-off-by: Masami Hiramatsu (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace_probe.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/trace/trace_probe.h ++++ b/kernel/trace/trace_probe.h +@@ -302,7 +302,7 @@ trace_probe_primary_from_call(struct tra + { + struct trace_probe_event *tpe = trace_probe_event_from_call(call); + +- return list_first_entry(&tpe->probes, struct trace_probe, list); ++ return list_first_entry_or_null(&tpe->probes, struct trace_probe, list); + } + + static inline struct list_head *trace_probe_probe_list(struct trace_probe *tp)