From: Greg Kroah-Hartman Date: Tue, 8 Apr 2025 10:10:54 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v5.4.292~36 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=96bba2da046da2c6e4be48aff8f670da22921626;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: ext4-don-t-over-report-free-space-or-inodes-in-statvfs.patch ext4-fix-oob-read-when-checking-dotdot-dir.patch jfs-add-index-corruption-check-to-dt_getpage.patch jfs-fix-slab-out-of-bounds-read-in-ea_get.patch mmc-sdhci-pxav3-set-need_rsp_busy-capability.patch nfsd-put-dl_stid-if-fail-to-queue-dl_recall.patch nfsd-skip-sending-cb_recall_any-when-the-backchannel-isn-t-up.patch tracing-ensure-module-defining-synth-event-cannot-be-unloaded-while-tracing.patch tracing-fix-use-after-free-in-print_graph_function_flags-during-tracer-switching.patch --- diff --git a/queue-5.10/ext4-don-t-over-report-free-space-or-inodes-in-statvfs.patch b/queue-5.10/ext4-don-t-over-report-free-space-or-inodes-in-statvfs.patch new file mode 100644 index 0000000000..88a9a03d8c --- /dev/null +++ b/queue-5.10/ext4-don-t-over-report-free-space-or-inodes-in-statvfs.patch @@ -0,0 +1,69 @@ +From f87d3af7419307ae26e705a2b2db36140db367a2 Mon Sep 17 00:00:00 2001 +From: Theodore Ts'o +Date: Fri, 14 Mar 2025 00:38:42 -0400 +Subject: ext4: don't over-report free space or inodes in statvfs + +From: Theodore Ts'o + +commit f87d3af7419307ae26e705a2b2db36140db367a2 upstream. + +This fixes an analogus bug that was fixed in xfs in commit +4b8d867ca6e2 ("xfs: don't over-report free space or inodes in +statvfs") where statfs can report misleading / incorrect information +where project quota is enabled, and the free space is less than the +remaining quota. + +This commit will resolve a test failure in generic/762 which tests for +this bug. + +Cc: stable@kernel.org +Fixes: 689c958cbe6b ("ext4: add project quota support") +Signed-off-by: Theodore Ts'o +Reviewed-by: "Darrick J. Wong" +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/super.c | 27 +++++++++++++++++---------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -6123,22 +6123,29 @@ static int ext4_statfs_project(struct su + dquot->dq_dqb.dqb_bhardlimit); + limit >>= sb->s_blocksize_bits; + +- if (limit && buf->f_blocks > limit) { ++ if (limit) { ++ uint64_t remaining = 0; ++ + curblock = (dquot->dq_dqb.dqb_curspace + + dquot->dq_dqb.dqb_rsvspace) >> sb->s_blocksize_bits; +- buf->f_blocks = limit; +- buf->f_bfree = buf->f_bavail = +- (buf->f_blocks > curblock) ? +- (buf->f_blocks - curblock) : 0; ++ if (limit > curblock) ++ remaining = limit - curblock; ++ ++ buf->f_blocks = min(buf->f_blocks, limit); ++ buf->f_bfree = min(buf->f_bfree, remaining); ++ buf->f_bavail = min(buf->f_bavail, remaining); + } + + limit = min_not_zero(dquot->dq_dqb.dqb_isoftlimit, + dquot->dq_dqb.dqb_ihardlimit); +- if (limit && buf->f_files > limit) { +- buf->f_files = limit; +- buf->f_ffree = +- (buf->f_files > dquot->dq_dqb.dqb_curinodes) ? +- (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0; ++ if (limit) { ++ uint64_t remaining = 0; ++ ++ if (limit > dquot->dq_dqb.dqb_curinodes) ++ remaining = limit - dquot->dq_dqb.dqb_curinodes; ++ ++ buf->f_files = min(buf->f_files, limit); ++ buf->f_ffree = min(buf->f_ffree, remaining); + } + + spin_unlock(&dquot->dq_dqb_lock); diff --git a/queue-5.10/ext4-fix-oob-read-when-checking-dotdot-dir.patch b/queue-5.10/ext4-fix-oob-read-when-checking-dotdot-dir.patch new file mode 100644 index 0000000000..935fc1aeb4 --- /dev/null +++ b/queue-5.10/ext4-fix-oob-read-when-checking-dotdot-dir.patch @@ -0,0 +1,100 @@ +From d5e206778e96e8667d3bde695ad372c296dc9353 Mon Sep 17 00:00:00 2001 +From: "Acs, Jakub" +Date: Thu, 20 Mar 2025 15:46:49 +0000 +Subject: ext4: fix OOB read when checking dotdot dir + +From: Acs, Jakub + +commit d5e206778e96e8667d3bde695ad372c296dc9353 upstream. + +Mounting a corrupted filesystem with directory which contains '.' dir +entry with rec_len == block size results in out-of-bounds read (later +on, when the corrupted directory is removed). + +ext4_empty_dir() assumes every ext4 directory contains at least '.' +and '..' as directory entries in the first data block. It first loads +the '.' dir entry, performs sanity checks by calling ext4_check_dir_entry() +and then uses its rec_len member to compute the location of '..' dir +entry (in ext4_next_entry). It assumes the '..' dir entry fits into the +same data block. + +If the rec_len of '.' is precisely one block (4KB), it slips through the +sanity checks (it is considered the last directory entry in the data +block) and leaves "struct ext4_dir_entry_2 *de" point exactly past the +memory slot allocated to the data block. The following call to +ext4_check_dir_entry() on new value of de then dereferences this pointer +which results in out-of-bounds mem access. + +Fix this by extending __ext4_check_dir_entry() to check for '.' dir +entries that reach the end of data block. Make sure to ignore the phony +dir entries for checksum (by checking name_len for non-zero). + +Note: This is reported by KASAN as use-after-free in case another +structure was recently freed from the slot past the bound, but it is +really an OOB read. + +This issue was found by syzkaller tool. + +Call Trace: +[ 38.594108] BUG: KASAN: slab-use-after-free in __ext4_check_dir_entry+0x67e/0x710 +[ 38.594649] Read of size 2 at addr ffff88802b41a004 by task syz-executor/5375 +[ 38.595158] +[ 38.595288] CPU: 0 UID: 0 PID: 5375 Comm: syz-executor Not tainted 6.14.0-rc7 #1 +[ 38.595298] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014 +[ 38.595304] Call Trace: +[ 38.595308] +[ 38.595311] dump_stack_lvl+0xa7/0xd0 +[ 38.595325] print_address_description.constprop.0+0x2c/0x3f0 +[ 38.595339] ? __ext4_check_dir_entry+0x67e/0x710 +[ 38.595349] print_report+0xaa/0x250 +[ 38.595359] ? __ext4_check_dir_entry+0x67e/0x710 +[ 38.595368] ? kasan_addr_to_slab+0x9/0x90 +[ 38.595378] kasan_report+0xab/0xe0 +[ 38.595389] ? __ext4_check_dir_entry+0x67e/0x710 +[ 38.595400] __ext4_check_dir_entry+0x67e/0x710 +[ 38.595410] ext4_empty_dir+0x465/0x990 +[ 38.595421] ? __pfx_ext4_empty_dir+0x10/0x10 +[ 38.595432] ext4_rmdir.part.0+0x29a/0xd10 +[ 38.595441] ? __dquot_initialize+0x2a7/0xbf0 +[ 38.595455] ? __pfx_ext4_rmdir.part.0+0x10/0x10 +[ 38.595464] ? __pfx___dquot_initialize+0x10/0x10 +[ 38.595478] ? down_write+0xdb/0x140 +[ 38.595487] ? __pfx_down_write+0x10/0x10 +[ 38.595497] ext4_rmdir+0xee/0x140 +[ 38.595506] vfs_rmdir+0x209/0x670 +[ 38.595517] ? lookup_one_qstr_excl+0x3b/0x190 +[ 38.595529] do_rmdir+0x363/0x3c0 +[ 38.595537] ? __pfx_do_rmdir+0x10/0x10 +[ 38.595544] ? strncpy_from_user+0x1ff/0x2e0 +[ 38.595561] __x64_sys_unlinkat+0xf0/0x130 +[ 38.595570] do_syscall_64+0x5b/0x180 +[ 38.595583] entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: ac27a0ec112a0 ("[PATCH] ext4: initial copy of files from ext3") +Signed-off-by: Jakub Acs +Cc: Theodore Ts'o +Cc: Andreas Dilger +Cc: linux-ext4@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Cc: Mahmoud Adam +Cc: stable@vger.kernel.org +Cc: security@kernel.org +Link: https://patch.msgid.link/b3ae36a6794c4a01944c7d70b403db5b@amazon.de +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/dir.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/ext4/dir.c ++++ b/fs/ext4/dir.c +@@ -88,6 +88,9 @@ int __ext4_check_dir_entry(const char *f + else if (unlikely(le32_to_cpu(de->inode) > + le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count))) + error_msg = "inode out of bounds"; ++ else if (unlikely(next_offset == size && de->name_len == 1 && ++ de->name[0] == '.')) ++ error_msg = "'.' directory cannot be the last in data block"; + else + return 0; + diff --git a/queue-5.10/jfs-add-index-corruption-check-to-dt_getpage.patch b/queue-5.10/jfs-add-index-corruption-check-to-dt_getpage.patch new file mode 100644 index 0000000000..a859c17902 --- /dev/null +++ b/queue-5.10/jfs-add-index-corruption-check-to-dt_getpage.patch @@ -0,0 +1,62 @@ +From a8dfb2168906944ea61acfc87846b816eeab882d Mon Sep 17 00:00:00 2001 +From: Roman Smirnov +Date: Wed, 26 Feb 2025 11:25:22 +0300 +Subject: jfs: add index corruption check to DT_GETPAGE() + +From: Roman Smirnov + +commit a8dfb2168906944ea61acfc87846b816eeab882d upstream. + +If the file system is corrupted, the header.stblindex variable +may become greater than 127. Because of this, an array access out +of bounds may occur: + +------------[ cut here ]------------ +UBSAN: array-index-out-of-bounds in fs/jfs/jfs_dtree.c:3096:10 +index 237 is out of range for type 'struct dtslot[128]' +CPU: 0 UID: 0 PID: 5822 Comm: syz-executor740 Not tainted 6.13.0-rc4-syzkaller-00110-g4099a71718b0 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 +Call Trace: + + __dump_stack lib/dump_stack.c:94 [inline] + dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 + ubsan_epilogue lib/ubsan.c:231 [inline] + __ubsan_handle_out_of_bounds+0x121/0x150 lib/ubsan.c:429 + dtReadFirst+0x622/0xc50 fs/jfs/jfs_dtree.c:3096 + dtReadNext fs/jfs/jfs_dtree.c:3147 [inline] + jfs_readdir+0x9aa/0x3c50 fs/jfs/jfs_dtree.c:2862 + wrap_directory_iterator+0x91/0xd0 fs/readdir.c:65 + iterate_dir+0x571/0x800 fs/readdir.c:108 + __do_sys_getdents64 fs/readdir.c:403 [inline] + __se_sys_getdents64+0x1e2/0x4b0 fs/readdir.c:389 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +---[ end trace ]--- + +Add a stblindex check for corruption. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=9120834fc227768625ba +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Cc: stable@vger.kernel.org +Signed-off-by: Roman Smirnov +Signed-off-by: Dave Kleikamp +Signed-off-by: Greg Kroah-Hartman +--- + fs/jfs/jfs_dtree.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/jfs/jfs_dtree.c ++++ b/fs/jfs/jfs_dtree.c +@@ -117,7 +117,8 @@ do { \ + if (!(RC)) { \ + if (((P)->header.nextindex > \ + (((BN) == 0) ? DTROOTMAXSLOT : (P)->header.maxslot)) || \ +- ((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT))) { \ ++ ((BN) && (((P)->header.maxslot > DTPAGEMAXSLOT) || \ ++ ((P)->header.stblindex >= DTPAGEMAXSLOT)))) { \ + BT_PUTPAGE(MP); \ + jfs_error((IP)->i_sb, \ + "DT_GETPAGE: dtree page corrupt\n"); \ diff --git a/queue-5.10/jfs-fix-slab-out-of-bounds-read-in-ea_get.patch b/queue-5.10/jfs-fix-slab-out-of-bounds-read-in-ea_get.patch new file mode 100644 index 0000000000..3bbc1fee8a --- /dev/null +++ b/queue-5.10/jfs-fix-slab-out-of-bounds-read-in-ea_get.patch @@ -0,0 +1,93 @@ +From fdf480da5837c23b146c4743c18de97202fcab37 Mon Sep 17 00:00:00 2001 +From: Qasim Ijaz +Date: Thu, 13 Feb 2025 21:05:53 +0000 +Subject: jfs: fix slab-out-of-bounds read in ea_get() + +From: Qasim Ijaz + +commit fdf480da5837c23b146c4743c18de97202fcab37 upstream. + +During the "size_check" label in ea_get(), the code checks if the extended +attribute list (xattr) size matches ea_size. If not, it logs +"ea_get: invalid extended attribute" and calls print_hex_dump(). + +Here, EALIST_SIZE(ea_buf->xattr) returns 4110417968, which exceeds +INT_MAX (2,147,483,647). Then ea_size is clamped: + + int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr)); + +Although clamp_t aims to bound ea_size between 0 and 4110417968, the upper +limit is treated as an int, causing an overflow above 2^31 - 1. This leads +"size" to wrap around and become negative (-184549328). + +The "size" is then passed to print_hex_dump() (called "len" in +print_hex_dump()), it is passed as type size_t (an unsigned +type), this is then stored inside a variable called +"int remaining", which is then assigned to "int linelen" which +is then passed to hex_dump_to_buffer(). In print_hex_dump() +the for loop, iterates through 0 to len-1, where len is +18446744073525002176, calling hex_dump_to_buffer() +on each iteration: + + for (i = 0; i < len; i += rowsize) { + linelen = min(remaining, rowsize); + remaining -= rowsize; + + hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, + linebuf, sizeof(linebuf), ascii); + + ... + } + +The expected stopping condition (i < len) is effectively broken +since len is corrupted and very large. This eventually leads to +the "ptr+i" being passed to hex_dump_to_buffer() to get closer +to the end of the actual bounds of "ptr", eventually an out of +bounds access is done in hex_dump_to_buffer() in the following +for loop: + + for (j = 0; j < len; j++) { + if (linebuflen < lx + 2) + goto overflow2; + ch = ptr[j]; + ... + } + +To fix this we should validate "EALIST_SIZE(ea_buf->xattr)" +before it is utilised. + +Reported-by: syzbot +Tested-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=4e6e7e4279d046613bc5 +Fixes: d9f9d96136cb ("jfs: xattr: check invalid xattr size more strictly") +Cc: stable@vger.kernel.org +Signed-off-by: Qasim Ijaz +Signed-off-by: Dave Kleikamp +Signed-off-by: Greg Kroah-Hartman +--- + fs/jfs/xattr.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +--- a/fs/jfs/xattr.c ++++ b/fs/jfs/xattr.c +@@ -559,11 +559,16 @@ static int ea_get(struct inode *inode, s + + size_check: + if (EALIST_SIZE(ea_buf->xattr) != ea_size) { +- int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr)); ++ if (unlikely(EALIST_SIZE(ea_buf->xattr) > INT_MAX)) { ++ printk(KERN_ERR "ea_get: extended attribute size too large: %u > INT_MAX\n", ++ EALIST_SIZE(ea_buf->xattr)); ++ } else { ++ int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr)); + +- printk(KERN_ERR "ea_get: invalid extended attribute\n"); +- print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, +- ea_buf->xattr, size, 1); ++ printk(KERN_ERR "ea_get: invalid extended attribute\n"); ++ print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1, ++ ea_buf->xattr, size, 1); ++ } + ea_release(inode, ea_buf); + rc = -EIO; + goto clean_up; diff --git a/queue-5.10/mmc-sdhci-pxav3-set-need_rsp_busy-capability.patch b/queue-5.10/mmc-sdhci-pxav3-set-need_rsp_busy-capability.patch new file mode 100644 index 0000000000..769f26a8dc --- /dev/null +++ b/queue-5.10/mmc-sdhci-pxav3-set-need_rsp_busy-capability.patch @@ -0,0 +1,47 @@ +From a41fcca4b342811b473bbaa4b44f1d34d87fcce6 Mon Sep 17 00:00:00 2001 +From: Karel Balej +Date: Mon, 10 Mar 2025 15:07:04 +0100 +Subject: mmc: sdhci-pxav3: set NEED_RSP_BUSY capability +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Karel Balej + +commit a41fcca4b342811b473bbaa4b44f1d34d87fcce6 upstream. + +Set the MMC_CAP_NEED_RSP_BUSY capability for the sdhci-pxav3 host to +prevent conversion of R1B responses to R1. Without this, the eMMC card +in the samsung,coreprimevelte smartphone using the Marvell PXA1908 SoC +with this mmc host doesn't probe with the ETIMEDOUT error originating in +__mmc_poll_for_busy. + +Note that the other issues reported for this phone and host, namely +floods of "Tuning failed, falling back to fixed sampling clock" dmesg +messages for the eMMC and unstable SDIO are not mitigated by this +change. + +Link: https://lore.kernel.org/r/20200310153340.5593-1-ulf.hansson@linaro.org/ +Link: https://lore.kernel.org/r/D7204PWIGQGI.1FRFQPPIEE2P9@matfyz.cz/ +Link: https://lore.kernel.org/r/20250115-pxa1908-lkml-v14-0-847d24f3665a@skole.hr/ +Cc: stable@vger.kernel.org +Signed-off-by: Karel Balej +Acked-by: Adrian Hunter +Tested-by: Duje Mihanović +Link: https://lore.kernel.org/r/20250310140707.23459-1-balejk@matfyz.cz +Signed-off-by: Ulf Hansson +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mmc/host/sdhci-pxav3.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/mmc/host/sdhci-pxav3.c ++++ b/drivers/mmc/host/sdhci-pxav3.c +@@ -401,6 +401,7 @@ static int sdhci_pxav3_probe(struct plat + if (!IS_ERR(pxa->clk_core)) + clk_prepare_enable(pxa->clk_core); + ++ host->mmc->caps |= MMC_CAP_NEED_RSP_BUSY; + /* enable 1/8V DDR capable */ + host->mmc->caps |= MMC_CAP_1_8V_DDR; + diff --git a/queue-5.10/nfsd-put-dl_stid-if-fail-to-queue-dl_recall.patch b/queue-5.10/nfsd-put-dl_stid-if-fail-to-queue-dl_recall.patch new file mode 100644 index 0000000000..62ec7d1a06 --- /dev/null +++ b/queue-5.10/nfsd-put-dl_stid-if-fail-to-queue-dl_recall.patch @@ -0,0 +1,102 @@ +From 230ca758453c63bd38e4d9f4a21db698f7abada8 Mon Sep 17 00:00:00 2001 +From: Li Lingfeng +Date: Thu, 13 Feb 2025 22:42:20 +0800 +Subject: nfsd: put dl_stid if fail to queue dl_recall + +From: Li Lingfeng + +commit 230ca758453c63bd38e4d9f4a21db698f7abada8 upstream. + +Before calling nfsd4_run_cb to queue dl_recall to the callback_wq, we +increment the reference count of dl_stid. +We expect that after the corresponding work_struct is processed, the +reference count of dl_stid will be decremented through the callback +function nfsd4_cb_recall_release. +However, if the call to nfsd4_run_cb fails, the incremented reference +count of dl_stid will not be decremented correspondingly, leading to the +following nfs4_stid leak: +unreferenced object 0xffff88812067b578 (size 344): + comm "nfsd", pid 2761, jiffies 4295044002 (age 5541.241s) + hex dump (first 32 bytes): + 01 00 00 00 6b 6b 6b 6b b8 02 c0 e2 81 88 ff ff ....kkkk........ + 00 6b 6b 6b 6b 6b 6b 6b 00 00 00 00 ad 4e ad de .kkkkkkk.....N.. + backtrace: + kmem_cache_alloc+0x4b9/0x700 + nfsd4_process_open1+0x34/0x300 + nfsd4_open+0x2d1/0x9d0 + nfsd4_proc_compound+0x7a2/0xe30 + nfsd_dispatch+0x241/0x3e0 + svc_process_common+0x5d3/0xcc0 + svc_process+0x2a3/0x320 + nfsd+0x180/0x2e0 + kthread+0x199/0x1d0 + ret_from_fork+0x30/0x50 + ret_from_fork_asm+0x1b/0x30 +unreferenced object 0xffff8881499f4d28 (size 368): + comm "nfsd", pid 2761, jiffies 4295044005 (age 5541.239s) + hex dump (first 32 bytes): + 01 00 00 00 00 00 00 00 30 4d 9f 49 81 88 ff ff ........0M.I.... + 30 4d 9f 49 81 88 ff ff 20 00 00 00 01 00 00 00 0M.I.... ....... + backtrace: + kmem_cache_alloc+0x4b9/0x700 + nfs4_alloc_stid+0x29/0x210 + alloc_init_deleg+0x92/0x2e0 + nfs4_set_delegation+0x284/0xc00 + nfs4_open_delegation+0x216/0x3f0 + nfsd4_process_open2+0x2b3/0xee0 + nfsd4_open+0x770/0x9d0 + nfsd4_proc_compound+0x7a2/0xe30 + nfsd_dispatch+0x241/0x3e0 + svc_process_common+0x5d3/0xcc0 + svc_process+0x2a3/0x320 + nfsd+0x180/0x2e0 + kthread+0x199/0x1d0 + ret_from_fork+0x30/0x50 + ret_from_fork_asm+0x1b/0x30 +Fix it by checking the result of nfsd4_run_cb and call nfs4_put_stid if +fail to queue dl_recall. + +Cc: stable@vger.kernel.org +Signed-off-by: Li Lingfeng +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -1069,6 +1069,12 @@ static struct nfs4_ol_stateid * nfs4_all + return openlockstateid(stid); + } + ++/* ++ * As the sc_free callback of deleg, this may be called by nfs4_put_stid ++ * in nfsd_break_one_deleg. ++ * Considering nfsd_break_one_deleg is called with the flc->flc_lock held, ++ * this function mustn't ever sleep. ++ */ + static void nfs4_free_deleg(struct nfs4_stid *stid) + { + struct nfs4_delegation *dp = delegstateid(stid); +@@ -4922,6 +4928,7 @@ static const struct nfsd4_callback_ops n + + static void nfsd_break_one_deleg(struct nfs4_delegation *dp) + { ++ bool queued; + /* + * We're assuming the state code never drops its reference + * without first removing the lease. Since we're in this lease +@@ -4930,7 +4937,10 @@ static void nfsd_break_one_deleg(struct + * we know it's safe to take a reference. + */ + refcount_inc(&dp->dl_stid.sc_count); +- WARN_ON_ONCE(!nfsd4_run_cb(&dp->dl_recall)); ++ queued = nfsd4_run_cb(&dp->dl_recall); ++ WARN_ON_ONCE(!queued); ++ if (!queued) ++ nfs4_put_stid(&dp->dl_stid); + } + + /* Called from break_lease() with flc_lock held. */ diff --git a/queue-5.10/nfsd-skip-sending-cb_recall_any-when-the-backchannel-isn-t-up.patch b/queue-5.10/nfsd-skip-sending-cb_recall_any-when-the-backchannel-isn-t-up.patch new file mode 100644 index 0000000000..f6479ce48d --- /dev/null +++ b/queue-5.10/nfsd-skip-sending-cb_recall_any-when-the-backchannel-isn-t-up.patch @@ -0,0 +1,60 @@ +From 8a388c1fabeb6606e16467b23242416c0dbeffad Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Tue, 14 Jan 2025 17:09:24 -0500 +Subject: NFSD: Skip sending CB_RECALL_ANY when the backchannel isn't up + +From: Chuck Lever + +commit 8a388c1fabeb6606e16467b23242416c0dbeffad upstream. + +NFSD sends CB_RECALL_ANY to clients when the server is low on +memory or that client has a large number of delegations outstanding. + +We've seen cases where NFSD attempts to send CB_RECALL_ANY requests +to disconnected clients, and gets confused. These calls never go +anywhere if a backchannel transport to the target client isn't +available. Before the server can send any backchannel operation, the +client has to connect first and then do a BIND_CONN_TO_SESSION. + +This patch doesn't address the root cause of the confusion, but +there's no need to queue up these optional operations if they can't +go anywhere. + +Fixes: 44df6f439a17 ("NFSD: add delegation reaper to react to low memory condition") +Reviewed-by: Jeff Layton +Cc: stable@vger.kernel.org +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -6246,14 +6246,19 @@ deleg_reaper(struct nfsd_net *nn) + spin_lock(&nn->client_lock); + list_for_each_safe(pos, next, &nn->client_lru) { + clp = list_entry(pos, struct nfs4_client, cl_lru); +- if (clp->cl_state != NFSD4_ACTIVE || +- list_empty(&clp->cl_delegations) || +- atomic_read(&clp->cl_delegs_in_recall) || +- test_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags) || +- (ktime_get_boottime_seconds() - +- clp->cl_ra_time < 5)) { ++ ++ if (clp->cl_state != NFSD4_ACTIVE) ++ continue; ++ if (list_empty(&clp->cl_delegations)) ++ continue; ++ if (atomic_read(&clp->cl_delegs_in_recall)) ++ continue; ++ if (test_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags)) ++ continue; ++ if (ktime_get_boottime_seconds() - clp->cl_ra_time < 5) ++ continue; ++ if (clp->cl_cb_state != NFSD4_CB_UP) + continue; +- } + list_add(&clp->cl_ra_cblist, &cblist); + + /* release in nfsd4_cb_recall_any_release */ diff --git a/queue-5.10/series b/queue-5.10/series index 5a798c7c3c..b150d3f932 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -214,3 +214,12 @@ x86-tsc-always-save-restore-tsc-sched_clock-on-suspend-resume.patch x86-mm-fix-flush_tlb_range-when-used-for-zapping-normal-pmds.patch acpi-nfit-fix-narrowing-conversion-in-acpi_nfit_ctl.patch acpi-resource-skip-irq-override-on-asus-vivobook-14-x1404vap.patch +mmc-sdhci-pxav3-set-need_rsp_busy-capability.patch +tracing-fix-use-after-free-in-print_graph_function_flags-during-tracer-switching.patch +tracing-ensure-module-defining-synth-event-cannot-be-unloaded-while-tracing.patch +ext4-don-t-over-report-free-space-or-inodes-in-statvfs.patch +ext4-fix-oob-read-when-checking-dotdot-dir.patch +jfs-fix-slab-out-of-bounds-read-in-ea_get.patch +jfs-add-index-corruption-check-to-dt_getpage.patch +nfsd-put-dl_stid-if-fail-to-queue-dl_recall.patch +nfsd-skip-sending-cb_recall_any-when-the-backchannel-isn-t-up.patch diff --git a/queue-5.10/tracing-ensure-module-defining-synth-event-cannot-be-unloaded-while-tracing.patch b/queue-5.10/tracing-ensure-module-defining-synth-event-cannot-be-unloaded-while-tracing.patch new file mode 100644 index 0000000000..0e184f62ba --- /dev/null +++ b/queue-5.10/tracing-ensure-module-defining-synth-event-cannot-be-unloaded-while-tracing.patch @@ -0,0 +1,76 @@ +From 21581dd4e7ff6c07d0ab577e3c32b13a74b31522 Mon Sep 17 00:00:00 2001 +From: Douglas Raillard +Date: Tue, 18 Mar 2025 18:09:05 +0000 +Subject: tracing: Ensure module defining synth event cannot be unloaded while tracing + +From: Douglas Raillard + +commit 21581dd4e7ff6c07d0ab577e3c32b13a74b31522 upstream. + +Currently, using synth_event_delete() will fail if the event is being +used (tracing in progress), but that is normally done in the module exit +function. At that stage, failing is problematic as returning a non-zero +status means the module will become locked (impossible to unload or +reload again). + +Instead, ensure the module exit function does not get called in the +first place by increasing the module refcnt when the event is enabled. + +Cc: stable@vger.kernel.org +Cc: Mathieu Desnoyers +Fixes: 35ca5207c2d11 ("tracing: Add synthetic event command generation functions") +Link: https://lore.kernel.org/20250318180906.226841-1-douglas.raillard@arm.com +Signed-off-by: Douglas Raillard +Acked-by: Masami Hiramatsu (Google) +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace_events_synth.c | 30 +++++++++++++++++++++++++++++- + 1 file changed, 29 insertions(+), 1 deletion(-) + +--- a/kernel/trace/trace_events_synth.c ++++ b/kernel/trace/trace_events_synth.c +@@ -749,6 +749,34 @@ static struct trace_event_fields synth_e + {} + }; + ++static int synth_event_reg(struct trace_event_call *call, ++ enum trace_reg type, void *data) ++{ ++ struct synth_event *event = container_of(call, struct synth_event, call); ++ ++ switch (type) { ++ case TRACE_REG_REGISTER: ++ case TRACE_REG_PERF_REGISTER: ++ if (!try_module_get(event->mod)) ++ return -EBUSY; ++ break; ++ default: ++ break; ++ } ++ ++ int ret = trace_event_reg(call, type, data); ++ ++ switch (type) { ++ case TRACE_REG_UNREGISTER: ++ case TRACE_REG_PERF_UNREGISTER: ++ module_put(event->mod); ++ break; ++ default: ++ break; ++ } ++ return ret; ++} ++ + static int register_synth_event(struct synth_event *event) + { + struct trace_event_call *call = &event->call; +@@ -778,7 +806,7 @@ static int register_synth_event(struct s + goto out; + } + call->flags = TRACE_EVENT_FL_TRACEPOINT; +- call->class->reg = trace_event_reg; ++ call->class->reg = synth_event_reg; + call->class->probe = trace_event_raw_event_synth; + call->data = event; + call->tp = event->tp; diff --git a/queue-5.10/tracing-fix-use-after-free-in-print_graph_function_flags-during-tracer-switching.patch b/queue-5.10/tracing-fix-use-after-free-in-print_graph_function_flags-during-tracer-switching.patch new file mode 100644 index 0000000000..aebff791b0 --- /dev/null +++ b/queue-5.10/tracing-fix-use-after-free-in-print_graph_function_flags-during-tracer-switching.patch @@ -0,0 +1,93 @@ +From 7f81f27b1093e4895e87b74143c59c055c3b1906 Mon Sep 17 00:00:00 2001 +From: Tengda Wu +Date: Thu, 20 Mar 2025 12:21:37 +0000 +Subject: tracing: Fix use-after-free in print_graph_function_flags during tracer switching + +From: Tengda Wu + +commit 7f81f27b1093e4895e87b74143c59c055c3b1906 upstream. + +Kairui reported a UAF issue in print_graph_function_flags() during +ftrace stress testing [1]. This issue can be reproduced if puting a +'mdelay(10)' after 'mutex_unlock(&trace_types_lock)' in s_start(), +and executing the following script: + + $ echo function_graph > current_tracer + $ cat trace > /dev/null & + $ sleep 5 # Ensure the 'cat' reaches the 'mdelay(10)' point + $ echo timerlat > current_tracer + +The root cause lies in the two calls to print_graph_function_flags +within print_trace_line during each s_show(): + + * One through 'iter->trace->print_line()'; + * Another through 'event->funcs->trace()', which is hidden in + print_trace_fmt() before print_trace_line returns. + +Tracer switching only updates the former, while the latter continues +to use the print_line function of the old tracer, which in the script +above is print_graph_function_flags. + +Moreover, when switching from the 'function_graph' tracer to the +'timerlat' tracer, s_start only calls graph_trace_close of the +'function_graph' tracer to free 'iter->private', but does not set +it to NULL. This provides an opportunity for 'event->funcs->trace()' +to use an invalid 'iter->private'. + +To fix this issue, set 'iter->private' to NULL immediately after +freeing it in graph_trace_close(), ensuring that an invalid pointer +is not passed to other tracers. Additionally, clean up the unnecessary +'iter->private = NULL' during each 'cat trace' when using wakeup and +irqsoff tracers. + + [1] https://lore.kernel.org/all/20231112150030.84609-1-ryncsn@gmail.com/ + +Cc: stable@vger.kernel.org +Cc: Masami Hiramatsu +Cc: Mathieu Desnoyers +Cc: Zheng Yejian +Link: https://lore.kernel.org/20250320122137.23635-1-wutengda@huaweicloud.com +Fixes: eecb91b9f98d ("tracing: Fix memleak due to race between current_tracer and trace") +Closes: https://lore.kernel.org/all/CAMgjq7BW79KDSCyp+tZHjShSzHsScSiJxn5ffskp-QzVM06fxw@mail.gmail.com/ +Reported-by: Kairui Song +Signed-off-by: Tengda Wu +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace_functions_graph.c | 1 + + kernel/trace/trace_irqsoff.c | 2 -- + kernel/trace/trace_sched_wakeup.c | 2 -- + 3 files changed, 1 insertion(+), 4 deletions(-) + +--- a/kernel/trace/trace_functions_graph.c ++++ b/kernel/trace/trace_functions_graph.c +@@ -1246,6 +1246,7 @@ void graph_trace_close(struct trace_iter + if (data) { + free_percpu(data->cpu_data); + kfree(data); ++ iter->private = NULL; + } + } + +--- a/kernel/trace/trace_irqsoff.c ++++ b/kernel/trace/trace_irqsoff.c +@@ -228,8 +228,6 @@ static void irqsoff_trace_open(struct tr + { + if (is_graph(iter->tr)) + graph_trace_open(iter); +- else +- iter->private = NULL; + } + + static void irqsoff_trace_close(struct trace_iterator *iter) +--- a/kernel/trace/trace_sched_wakeup.c ++++ b/kernel/trace/trace_sched_wakeup.c +@@ -171,8 +171,6 @@ static void wakeup_trace_open(struct tra + { + if (is_graph(iter->tr)) + graph_trace_open(iter); +- else +- iter->private = NULL; + } + + static void wakeup_trace_close(struct trace_iterator *iter)