From: Greg Kroah-Hartman Date: Fri, 6 Dec 2024 12:39:25 +0000 (+0100) Subject: 5.15-stable patches X-Git-Tag: v6.6.64~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ae9b51595adf819246eff2b2411ea73d846cc027;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: btrfs-don-t-bug_on-on-enomem-from-btrfs_lookup_extent_info-in-walk_down_proc.patch dm-thin-add-missing-destroy_work_on_stack.patch nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch nfsd-make-sure-exp-active-before-svc_export_show.patch pci-rockchip-ep-fix-address-translation-unit-programming.patch --- diff --git a/queue-5.15/btrfs-don-t-bug_on-on-enomem-from-btrfs_lookup_extent_info-in-walk_down_proc.patch b/queue-5.15/btrfs-don-t-bug_on-on-enomem-from-btrfs_lookup_extent_info-in-walk_down_proc.patch new file mode 100644 index 00000000000..0f0ef7f1091 --- /dev/null +++ b/queue-5.15/btrfs-don-t-bug_on-on-enomem-from-btrfs_lookup_extent_info-in-walk_down_proc.patch @@ -0,0 +1,31 @@ +From a580fb2c3479d993556e1c31b237c9e5be4944a3 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Tue, 7 May 2024 14:12:10 -0400 +Subject: btrfs: don't BUG_ON on ENOMEM from btrfs_lookup_extent_info() in walk_down_proc() + +From: Josef Bacik + +commit a580fb2c3479d993556e1c31b237c9e5be4944a3 upstream. + +We handle errors here properly, ENOMEM isn't fatal, return the error. + +Signed-off-by: Josef Bacik +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +Signed-off-by: Keerthana K +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/extent-tree.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/fs/btrfs/extent-tree.c ++++ b/fs/btrfs/extent-tree.c +@@ -5099,7 +5099,6 @@ static noinline int walk_down_proc(struc + eb->start, level, 1, + &wc->refs[level], + &wc->flags[level]); +- BUG_ON(ret == -ENOMEM); + if (ret) + return ret; + if (unlikely(wc->refs[level] == 0)) { diff --git a/queue-5.15/dm-thin-add-missing-destroy_work_on_stack.patch b/queue-5.15/dm-thin-add-missing-destroy_work_on_stack.patch new file mode 100644 index 00000000000..1ccaed51d87 --- /dev/null +++ b/queue-5.15/dm-thin-add-missing-destroy_work_on_stack.patch @@ -0,0 +1,31 @@ +From e74fa2447bf9ed03d085b6d91f0256cc1b53f1a8 Mon Sep 17 00:00:00 2001 +From: Yuan Can +Date: Wed, 6 Nov 2024 09:03:12 +0800 +Subject: dm thin: Add missing destroy_work_on_stack() + +From: Yuan Can + +commit e74fa2447bf9ed03d085b6d91f0256cc1b53f1a8 upstream. + +This commit add missed destroy_work_on_stack() operations for pw->worker in +pool_work_wait(). + +Fixes: e7a3e871d895 ("dm thin: cleanup noflush_work to use a proper completion") +Cc: stable@vger.kernel.org +Signed-off-by: Yuan Can +Signed-off-by: Mikulas Patocka +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-thin.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/md/dm-thin.c ++++ b/drivers/md/dm-thin.c +@@ -2468,6 +2468,7 @@ static void pool_work_wait(struct pool_w + init_completion(&pw->complete); + queue_work(pool->wq, &pw->worker); + wait_for_completion(&pw->complete); ++ destroy_work_on_stack(&pw->worker); + } + + /*----------------------------------------------------------------*/ diff --git a/queue-5.15/nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch b/queue-5.15/nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch new file mode 100644 index 00000000000..c847e3da226 --- /dev/null +++ b/queue-5.15/nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch @@ -0,0 +1,195 @@ +From 98100e88dd8865999dc6379a3356cd799795fe7b Mon Sep 17 00:00:00 2001 +From: Yang Erkun +Date: Tue, 5 Nov 2024 19:03:14 +0800 +Subject: nfsd: fix nfs4_openowner leak when concurrent nfsd4_open occur + +From: Yang Erkun + +commit 98100e88dd8865999dc6379a3356cd799795fe7b upstream. + +The action force umount(umount -f) will attempt to kill all rpc_task even +umount operation may ultimately fail if some files remain open. +Consequently, if an action attempts to open a file, it can potentially +send two rpc_task to nfs server. + + NFS CLIENT +thread1 thread2 +open("file") +... +nfs4_do_open + _nfs4_do_open + _nfs4_open_and_get_state + _nfs4_proc_open + nfs4_run_open_task + /* rpc_task1 */ + rpc_run_task + rpc_wait_for_completion_task + + umount -f + nfs_umount_begin + rpc_killall_tasks + rpc_signal_task + rpc_task1 been wakeup + and return -512 + _nfs4_do_open // while loop + ... + nfs4_run_open_task + /* rpc_task2 */ + rpc_run_task + rpc_wait_for_completion_task + +While processing an open request, nfsd will first attempt to find or +allocate an nfs4_openowner. If it finds an nfs4_openowner that is not +marked as NFS4_OO_CONFIRMED, this nfs4_openowner will released. Since +two rpc_task can attempt to open the same file simultaneously from the +client to server, and because two instances of nfsd can run +concurrently, this situation can lead to lots of memory leak. +Additionally, when we echo 0 to /proc/fs/nfsd/threads, warning will be +triggered. + + NFS SERVER +nfsd1 nfsd2 echo 0 > /proc/fs/nfsd/threads + +nfsd4_open + nfsd4_process_open1 + find_or_alloc_open_stateowner + // alloc oo1, stateid1 + nfsd4_open + nfsd4_process_open1 + find_or_alloc_open_stateowner + // find oo1, without NFS4_OO_CONFIRMED + release_openowner + unhash_openowner_locked + list_del_init(&oo->oo_perclient) + // cannot find this oo + // from client, LEAK!!! + alloc_stateowner // alloc oo2 + + nfsd4_process_open2 + init_open_stateid + // associate oo1 + // with stateid1, stateid1 LEAK!!! + nfs4_get_vfs_file + // alloc nfsd_file1 and nfsd_file_mark1 + // all LEAK!!! + + nfsd4_process_open2 + ... + + write_threads + ... + nfsd_destroy_serv + nfsd_shutdown_net + nfs4_state_shutdown_net + nfs4_state_destroy_net + destroy_client + __destroy_client + // won't find oo1!!! + nfsd_shutdown_generic + nfsd_file_cache_shutdown + kmem_cache_destroy + for nfsd_file_slab + and nfsd_file_mark_slab + // bark since nfsd_file1 + // and nfsd_file_mark1 + // still alive + +======================================================================= +BUG nfsd_file (Not tainted): Objects remaining in nfsd_file on +__kmem_cache_shutdown() +----------------------------------------------------------------------- + +Slab 0xffd4000004438a80 objects=34 used=1 fp=0xff11000110e2ad28 +flags=0x17ffffc0000240(workingset|head|node=0|zone=2|lastcpupid=0x1fffff) +CPU: 4 UID: 0 PID: 757 Comm: sh Not tainted 6.12.0-rc6+ #19 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +1.16.1-2.fc37 04/01/2014 +Call Trace: + + dump_stack_lvl+0x53/0x70 + slab_err+0xb0/0xf0 + __kmem_cache_shutdown+0x15c/0x310 + kmem_cache_destroy+0x66/0x160 + nfsd_file_cache_shutdown+0xac/0x210 [nfsd] + nfsd_destroy_serv+0x251/0x2a0 [nfsd] + nfsd_svc+0x125/0x1e0 [nfsd] + write_threads+0x16a/0x2a0 [nfsd] + nfsctl_transaction_write+0x74/0xa0 [nfsd] + vfs_write+0x1ae/0x6d0 + ksys_write+0xc1/0x160 + do_syscall_64+0x5f/0x170 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Disabling lock debugging due to kernel taint +Object 0xff11000110e2ac38 @offset=3128 +Allocated in nfsd_file_do_acquire+0x20f/0xa30 [nfsd] age=1635 cpu=3 +pid=800 + nfsd_file_do_acquire+0x20f/0xa30 [nfsd] + nfsd_file_acquire_opened+0x5f/0x90 [nfsd] + nfs4_get_vfs_file+0x4c9/0x570 [nfsd] + nfsd4_process_open2+0x713/0x1070 [nfsd] + nfsd4_open+0x74b/0x8b0 [nfsd] + nfsd4_proc_compound+0x70b/0xc20 [nfsd] + nfsd_dispatch+0x1b4/0x3a0 [nfsd] + svc_process_common+0x5b8/0xc50 [sunrpc] + svc_process+0x2ab/0x3b0 [sunrpc] + svc_handle_xprt+0x681/0xa20 [sunrpc] + nfsd+0x183/0x220 [nfsd] + kthread+0x199/0x1e0 + ret_from_fork+0x31/0x60 + ret_from_fork_asm+0x1a/0x30 + +Add nfs4_openowner_unhashed to help found unhashed nfs4_openowner, and +break nfsd4_open process to fix this problem. + +Cc: stable@vger.kernel.org # v5.4+ +Reviewed-by: Jeff Layton +Signed-off-by: Yang Erkun +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4state.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -1628,6 +1628,14 @@ static void release_open_stateid(struct + free_ol_stateid_reaplist(&reaplist); + } + ++static bool nfs4_openowner_unhashed(struct nfs4_openowner *oo) ++{ ++ lockdep_assert_held(&oo->oo_owner.so_client->cl_lock); ++ ++ return list_empty(&oo->oo_owner.so_strhash) && ++ list_empty(&oo->oo_perclient); ++} ++ + static void unhash_openowner_locked(struct nfs4_openowner *oo) + { + struct nfs4_client *clp = oo->oo_owner.so_client; +@@ -4638,6 +4646,12 @@ retry: + spin_lock(&oo->oo_owner.so_client->cl_lock); + spin_lock(&fp->fi_lock); + ++ if (nfs4_openowner_unhashed(oo)) { ++ mutex_unlock(&stp->st_mutex); ++ stp = NULL; ++ goto out_unlock; ++ } ++ + retstp = nfsd4_find_existing_open(fp, open); + if (retstp) + goto out_unlock; +@@ -5712,6 +5726,11 @@ nfsd4_process_open2(struct svc_rqst *rqs + + if (!stp) { + stp = init_open_stateid(fp, open); ++ if (!stp) { ++ status = nfserr_jukebox; ++ goto out; ++ } ++ + if (!open->op_stp) + new_stp = true; + } diff --git a/queue-5.15/nfsd-make-sure-exp-active-before-svc_export_show.patch b/queue-5.15/nfsd-make-sure-exp-active-before-svc_export_show.patch new file mode 100644 index 00000000000..7021f306c05 --- /dev/null +++ b/queue-5.15/nfsd-make-sure-exp-active-before-svc_export_show.patch @@ -0,0 +1,60 @@ +From be8f982c369c965faffa198b46060f8853e0f1f0 Mon Sep 17 00:00:00 2001 +From: Yang Erkun +Date: Mon, 21 Oct 2024 22:23:41 +0800 +Subject: nfsd: make sure exp active before svc_export_show + +From: Yang Erkun + +commit be8f982c369c965faffa198b46060f8853e0f1f0 upstream. + +The function `e_show` was called with protection from RCU. This only +ensures that `exp` will not be freed. Therefore, the reference count for +`exp` can drop to zero, which will trigger a refcount use-after-free +warning when `exp_get` is called. To resolve this issue, use +`cache_get_rcu` to ensure that `exp` remains active. + +------------[ cut here ]------------ +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 3 PID: 819 at lib/refcount.c:25 +refcount_warn_saturate+0xb1/0x120 +CPU: 3 UID: 0 PID: 819 Comm: cat Not tainted 6.12.0-rc3+ #1 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS +1.16.1-2.fc37 04/01/2014 +RIP: 0010:refcount_warn_saturate+0xb1/0x120 +... +Call Trace: + + e_show+0x20b/0x230 [nfsd] + seq_read_iter+0x589/0x770 + seq_read+0x1e5/0x270 + vfs_read+0x125/0x530 + ksys_read+0xc1/0x160 + do_syscall_64+0x5f/0x170 + entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: bf18f163e89c ("NFSD: Using exp_get for export getting") +Cc: stable@vger.kernel.org # 4.20+ +Signed-off-by: Yang Erkun +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/export.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/export.c ++++ b/fs/nfsd/export.c +@@ -1324,9 +1324,12 @@ static int e_show(struct seq_file *m, vo + return 0; + } + +- exp_get(exp); ++ if (!cache_get_rcu(&exp->h)) ++ return 0; ++ + if (cache_check(cd, &exp->h, NULL)) + return 0; ++ + exp_put(exp); + return svc_export_show(m, cd, cp); + } diff --git a/queue-5.15/pci-rockchip-ep-fix-address-translation-unit-programming.patch b/queue-5.15/pci-rockchip-ep-fix-address-translation-unit-programming.patch new file mode 100644 index 00000000000..beb42c15ab5 --- /dev/null +++ b/queue-5.15/pci-rockchip-ep-fix-address-translation-unit-programming.patch @@ -0,0 +1,98 @@ +From 64f093c4d99d797b68b407a9d8767aadc3e3ea7a Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Thu, 17 Oct 2024 10:58:36 +0900 +Subject: PCI: rockchip-ep: Fix address translation unit programming +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Damien Le Moal + +commit 64f093c4d99d797b68b407a9d8767aadc3e3ea7a upstream. + +The Rockchip PCIe endpoint controller handles PCIe transfers addresses +by masking the lower bits of the programmed PCI address and using the +same number of lower bits masked from the CPU address space used for the +mapping. For a PCI mapping of bytes starting from , +the number of bits masked is the number of address bits changing in the +address range [pci_addr..pci_addr + size - 1]. + +However, rockchip_pcie_prog_ep_ob_atu() calculates num_pass_bits only +using the size of the mapping, resulting in an incorrect number of mask +bits depending on the value of the PCI address to map. + +Fix this by introducing the helper function +rockchip_pcie_ep_ob_atu_num_bits() to correctly calculate the number of +mask bits to use to program the address translation unit. The number of +mask bits is calculated depending on both the PCI address and size of +the mapping, and clamped between 8 and 20 using the macros +ROCKCHIP_PCIE_AT_MIN_NUM_BITS and ROCKCHIP_PCIE_AT_MAX_NUM_BITS. As +defined in the Rockchip RK3399 TRM V1.3 Part2, Sections 17.5.5.1.1 and +17.6.8.2.1, this clamping is necessary because: + + 1) The lower 8 bits of the PCI address to be mapped by the outbound + region are ignored. So a minimum of 8 address bits are needed and + imply that the PCI address must be aligned to 256. + + 2) The outbound memory regions are 1MB in size. So while we can specify + up to 63-bits for the PCI address (num_bits filed uses bits 0 to 5 of + the outbound address region 0 register), we must limit the number of + valid address bits to 20 to match the memory window maximum size (1 + << 20 = 1MB). + +Fixes: cf590b078391 ("PCI: rockchip: Add EP driver for Rockchip PCIe controller") +Link: https://lore.kernel.org/r/20241017015849.190271-2-dlemoal@kernel.org +Signed-off-by: Damien Le Moal +Signed-off-by: Krzysztof Wilczyński +Signed-off-by: Bjorn Helgaas +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/controller/pcie-rockchip-ep.c | 16 +++++++++++++--- + drivers/pci/controller/pcie-rockchip.h | 4 ++++ + 2 files changed, 17 insertions(+), 3 deletions(-) + +--- a/drivers/pci/controller/pcie-rockchip-ep.c ++++ b/drivers/pci/controller/pcie-rockchip-ep.c +@@ -63,15 +63,25 @@ static void rockchip_pcie_clear_ep_ob_at + ROCKCHIP_PCIE_AT_OB_REGION_DESC1(region)); + } + ++static int rockchip_pcie_ep_ob_atu_num_bits(struct rockchip_pcie *rockchip, ++ u64 pci_addr, size_t size) ++{ ++ int num_pass_bits = fls64(pci_addr ^ (pci_addr + size - 1)); ++ ++ return clamp(num_pass_bits, ++ ROCKCHIP_PCIE_AT_MIN_NUM_BITS, ++ ROCKCHIP_PCIE_AT_MAX_NUM_BITS); ++} ++ + static void rockchip_pcie_prog_ep_ob_atu(struct rockchip_pcie *rockchip, u8 fn, + u32 r, u64 cpu_addr, u64 pci_addr, + size_t size) + { +- int num_pass_bits = fls64(size - 1); ++ int num_pass_bits; + u32 addr0, addr1, desc0; + +- if (num_pass_bits < 8) +- num_pass_bits = 8; ++ num_pass_bits = rockchip_pcie_ep_ob_atu_num_bits(rockchip, ++ pci_addr, size); + + addr0 = ((num_pass_bits - 1) & PCIE_CORE_OB_REGION_ADDR0_NUM_BITS) | + (lower_32_bits(pci_addr) & PCIE_CORE_OB_REGION_ADDR0_LO_ADDR); +--- a/drivers/pci/controller/pcie-rockchip.h ++++ b/drivers/pci/controller/pcie-rockchip.h +@@ -246,6 +246,10 @@ + (PCIE_EP_PF_CONFIG_REGS_BASE + (((fn) << 12) & GENMASK(19, 12))) + #define ROCKCHIP_PCIE_EP_VIRT_FUNC_BASE(fn) \ + (PCIE_EP_PF_CONFIG_REGS_BASE + 0x10000 + (((fn) << 12) & GENMASK(19, 12))) ++ ++#define ROCKCHIP_PCIE_AT_MIN_NUM_BITS 8 ++#define ROCKCHIP_PCIE_AT_MAX_NUM_BITS 20 ++ + #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR0(fn, bar) \ + (PCIE_CORE_AXI_CONF_BASE + 0x0828 + (fn) * 0x0040 + (bar) * 0x0008) + #define ROCKCHIP_PCIE_AT_IB_EP_FUNC_BAR_ADDR1(fn, bar) \ diff --git a/queue-5.15/series b/queue-5.15/series index 763fc7a3098..9ea65cfca23 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -388,3 +388,8 @@ scsi-ufs-exynos-fix-hibern8-notify-callbacks.patch i3c-master-fix-miss-free-init_dyn_addr-at-i3c_master_put_i3c_addrs.patch pci-keystone-add-link-up-check-to-ks_pcie_other_map_bus.patch ovl-properly-handle-large-files-in-ovl_security_fileattr.patch +dm-thin-add-missing-destroy_work_on_stack.patch +pci-rockchip-ep-fix-address-translation-unit-programming.patch +nfsd-make-sure-exp-active-before-svc_export_show.patch +nfsd-fix-nfs4_openowner-leak-when-concurrent-nfsd4_open-occur.patch +btrfs-don-t-bug_on-on-enomem-from-btrfs_lookup_extent_info-in-walk_down_proc.patch