From: Greg Kroah-Hartman Date: Tue, 12 Aug 2025 09:12:02 +0000 (+0200) Subject: 6.16-stable patches X-Git-Tag: v6.1.148~61 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1781fac4fd74e153f6e0618fac141b1d770f873b;p=thirdparty%2Fkernel%2Fstable-queue.git 6.16-stable patches added patches: nfsd-avoid-ref-leak-in-nfsd_open_local_fh.patch nfsd-don-t-set-the-ctime-on-delegated-atime-updates.patch sunrpc-fix-handling-of-server-side-tls-alerts.patch --- diff --git a/queue-6.16/nfsd-avoid-ref-leak-in-nfsd_open_local_fh.patch b/queue-6.16/nfsd-avoid-ref-leak-in-nfsd_open_local_fh.patch new file mode 100644 index 0000000000..c97d6496df --- /dev/null +++ b/queue-6.16/nfsd-avoid-ref-leak-in-nfsd_open_local_fh.patch @@ -0,0 +1,50 @@ +From e5a73150776f18547ee685c9f6bfafe549714899 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Fri, 18 Jul 2025 11:26:14 +1000 +Subject: nfsd: avoid ref leak in nfsd_open_local_fh() + +From: NeilBrown + +commit e5a73150776f18547ee685c9f6bfafe549714899 upstream. + +If two calls to nfsd_open_local_fh() race and both successfully call +nfsd_file_acquire_local(), they will both get an extra reference to the +net to accompany the file reference stored in *pnf. + +One of them will fail to store (using xchg()) the file reference in +*pnf and will drop that reference but WON'T drop the accompanying +reference to the net. This leak means that when the nfs server is shut +down it will hang in nfsd_shutdown_net() waiting for +&nn->nfsd_net_free_done. + +This patch adds the missing nfsd_net_put(). + +Reported-by: Mike Snitzer +Fixes: e6f7e1487ab5 ("nfs_localio: simplify interface to nfsd for getting nfsd_file") +Cc: stable@vger.kernel.org +Signed-off-by: NeilBrown +Tested-by: Mike Snitzer +Reviewed-by: Mike Snitzer +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/localio.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/nfsd/localio.c ++++ b/fs/nfsd/localio.c +@@ -103,10 +103,11 @@ nfsd_open_local_fh(struct net *net, stru + if (nfsd_file_get(new) == NULL) + goto again; + /* +- * Drop the ref we were going to install and the +- * one we were going to return. ++ * Drop the ref we were going to install (both file and ++ * net) and the one we were going to return (only file). + */ + nfsd_file_put(localio); ++ nfsd_net_put(net); + nfsd_file_put(localio); + localio = new; + } diff --git a/queue-6.16/nfsd-don-t-set-the-ctime-on-delegated-atime-updates.patch b/queue-6.16/nfsd-don-t-set-the-ctime-on-delegated-atime-updates.patch new file mode 100644 index 0000000000..4c3fa50e42 --- /dev/null +++ b/queue-6.16/nfsd-don-t-set-the-ctime-on-delegated-atime-updates.patch @@ -0,0 +1,57 @@ +From f9a348e0de19226fc3c7e81de7677d3fa2c4b2d8 Mon Sep 17 00:00:00 2001 +From: Jeff Layton +Date: Wed, 16 Jul 2025 09:34:29 -0400 +Subject: nfsd: don't set the ctime on delegated atime updates + +From: Jeff Layton + +commit f9a348e0de19226fc3c7e81de7677d3fa2c4b2d8 upstream. + +Clients will typically precede a DELEGRETURN for a delegation with +delegated timestamp with a SETATTR to set the timestamps on the server +to match what the client has. + +knfsd implements this by using the nfsd_setattr() infrastructure, which +will set ATTR_CTIME on any update that goes to notify_change(). This is +problematic as it means that the client will get a spurious ctime +update when updating the atime. + +POSIX unfortunately doesn't phrase it succinctly, but updating the atime +due to reads should not update the ctime. In this case, the client is +sending a SETATTR to update the atime on the server to match its latest +value. The ctime should not be advanced in this case as that would +incorrectly indicate a change to the inode. + +Fix this by not implicitly setting ATTR_CTIME when ATTR_DELEG is set in +__nfsd_setattr(). The decoder for FATTR4_WORD2_TIME_DELEG_MODIFY already +sets ATTR_CTIME, so this is sufficient to make it skip setting the ctime +on atime-only updates. + +Fixes: 7e13f4f8d27d ("nfsd: handle delegated timestamps in SETATTR") +Cc: stable@vger.kernel.org +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/vfs.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/fs/nfsd/vfs.c ++++ b/fs/nfsd/vfs.c +@@ -470,7 +470,15 @@ static int __nfsd_setattr(struct dentry + if (!iap->ia_valid) + return 0; + +- iap->ia_valid |= ATTR_CTIME; ++ /* ++ * If ATTR_DELEG is set, then this is an update from a client that ++ * holds a delegation. If this is an update for only the atime, the ++ * ctime should not be changed. If the update contains the mtime ++ * too, then ATTR_CTIME should already be set. ++ */ ++ if (!(iap->ia_valid & ATTR_DELEG)) ++ iap->ia_valid |= ATTR_CTIME; ++ + return notify_change(&nop_mnt_idmap, dentry, iap, NULL); + } + diff --git a/queue-6.16/pwm-rockchip-round-period-duty-down-on-apply-up-on-g.patch b/queue-6.16/pwm-rockchip-round-period-duty-down-on-apply-up-on-g.patch deleted file mode 100644 index df54418781..0000000000 --- a/queue-6.16/pwm-rockchip-round-period-duty-down-on-apply-up-on-g.patch +++ /dev/null @@ -1,122 +0,0 @@ -From 51144efa3159cd95ab37e786c982822a060d7d1a Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 16 Jun 2025 17:14:17 +0200 -Subject: pwm: rockchip: Round period/duty down on apply, up on get -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -From: Nicolas Frattaroli - -[ Upstream commit 0b4d1abe5ca568c5b7f667345ec2b5ad0fb2e54b ] - -With CONFIG_PWM_DEBUG=y, the rockchip PWM driver produces warnings like -this: - - rockchip-pwm fd8b0010.pwm: .apply is supposed to round down - duty_cycle (requested: 23529/50000, applied: 23542/50000) - -This is because the driver chooses ROUND_CLOSEST for purported -idempotency reasons. However, it's possible to keep idempotency while -always rounding down in .apply(). - -Do this by making .get_state() always round up, and making .apply() -always round down. This is done with u64 maths, and setting both period -and duty to U32_MAX (the biggest the hardware can support) if they would -exceed their 32 bits confines. - -Fixes: 12f9ce4a5198 ("pwm: rockchip: Fix period and duty cycle approximation") -Fixes: 1ebb74cf3537 ("pwm: rockchip: Add support for hardware readout") -Signed-off-by: Nicolas Frattaroli -Link: https://lore.kernel.org/r/20250616-rockchip-pwm-rounding-fix-v2-1-a9c65acad7b6@collabora.com -Signed-off-by: Uwe Kleine-König -Signed-off-by: Sasha Levin ---- - drivers/pwm/pwm-rockchip.c | 33 ++++++++++++++++++++------------- - 1 file changed, 20 insertions(+), 13 deletions(-) - -diff --git a/drivers/pwm/pwm-rockchip.c b/drivers/pwm/pwm-rockchip.c -index c5f50e5eaf41..67b85bdb491b 100644 ---- a/drivers/pwm/pwm-rockchip.c -+++ b/drivers/pwm/pwm-rockchip.c -@@ -8,6 +8,8 @@ - - #include - #include -+#include -+#include - #include - #include - #include -@@ -61,6 +63,7 @@ static int rockchip_pwm_get_state(struct pwm_chip *chip, - struct pwm_state *state) - { - struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); -+ u64 prescaled_ns = (u64)pc->data->prescaler * NSEC_PER_SEC; - u32 enable_conf = pc->data->enable_conf; - unsigned long clk_rate; - u64 tmp; -@@ -78,12 +81,12 @@ static int rockchip_pwm_get_state(struct pwm_chip *chip, - clk_rate = clk_get_rate(pc->clk); - - tmp = readl_relaxed(pc->base + pc->data->regs.period); -- tmp *= pc->data->prescaler * NSEC_PER_SEC; -- state->period = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); -+ tmp *= prescaled_ns; -+ state->period = DIV_U64_ROUND_UP(tmp, clk_rate); - - tmp = readl_relaxed(pc->base + pc->data->regs.duty); -- tmp *= pc->data->prescaler * NSEC_PER_SEC; -- state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); -+ tmp *= prescaled_ns; -+ state->duty_cycle = DIV_U64_ROUND_UP(tmp, clk_rate); - - val = readl_relaxed(pc->base + pc->data->regs.ctrl); - state->enabled = (val & enable_conf) == enable_conf; -@@ -103,8 +106,9 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, - const struct pwm_state *state) - { - struct rockchip_pwm_chip *pc = to_rockchip_pwm_chip(chip); -- unsigned long period, duty; -- u64 clk_rate, div; -+ u64 prescaled_ns = (u64)pc->data->prescaler * NSEC_PER_SEC; -+ u64 clk_rate, tmp; -+ u32 period_ticks, duty_ticks; - u32 ctrl; - - clk_rate = clk_get_rate(pc->clk); -@@ -114,12 +118,15 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, - * bits, every possible input period can be obtained using the - * default prescaler value for all practical clock rate values. - */ -- div = clk_rate * state->period; -- period = DIV_ROUND_CLOSEST_ULL(div, -- pc->data->prescaler * NSEC_PER_SEC); -+ tmp = mul_u64_u64_div_u64(clk_rate, state->period, prescaled_ns); -+ if (tmp > U32_MAX) -+ tmp = U32_MAX; -+ period_ticks = tmp; - -- div = clk_rate * state->duty_cycle; -- duty = DIV_ROUND_CLOSEST_ULL(div, pc->data->prescaler * NSEC_PER_SEC); -+ tmp = mul_u64_u64_div_u64(clk_rate, state->duty_cycle, prescaled_ns); -+ if (tmp > U32_MAX) -+ tmp = U32_MAX; -+ duty_ticks = tmp; - - /* - * Lock the period and duty of previous configuration, then -@@ -131,8 +138,8 @@ static void rockchip_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, - writel_relaxed(ctrl, pc->base + pc->data->regs.ctrl); - } - -- writel(period, pc->base + pc->data->regs.period); -- writel(duty, pc->base + pc->data->regs.duty); -+ writel(period_ticks, pc->base + pc->data->regs.period); -+ writel(duty_ticks, pc->base + pc->data->regs.duty); - - if (pc->data->supports_polarity) { - ctrl &= ~PWM_POLARITY_MASK; --- -2.39.5 - diff --git a/queue-6.16/sched-do-not-call-__put_task_struct-on-rt-if-pi_bloc.patch b/queue-6.16/sched-do-not-call-__put_task_struct-on-rt-if-pi_bloc.patch deleted file mode 100644 index 59257020da..0000000000 --- a/queue-6.16/sched-do-not-call-__put_task_struct-on-rt-if-pi_bloc.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 7bed29f5ad955444283dca82476dd92c59923f73 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Mon, 7 Jul 2025 11:03:59 -0300 -Subject: sched: Do not call __put_task_struct() on rt if pi_blocked_on is set - -From: Luis Claudio R. Goncalves - -[ Upstream commit 8671bad873ebeb082afcf7b4501395c374da6023 ] - -With PREEMPT_RT enabled, some of the calls to put_task_struct() coming -from rt_mutex_adjust_prio_chain() could happen in preemptible context and -with a mutex enqueued. That could lead to this sequence: - - rt_mutex_adjust_prio_chain() - put_task_struct() - __put_task_struct() - sched_ext_free() - spin_lock_irqsave() - rtlock_lock() ---> TRIGGERS - lockdep_assert(!current->pi_blocked_on); - -This is not a SCHED_EXT bug. The first cleanup function called by -__put_task_struct() is sched_ext_free() and it happens to take a -(RT) spin_lock, which in the scenario described above, would trigger -the lockdep assertion of "!current->pi_blocked_on". - -Crystal Wood was able to identify the problem as __put_task_struct() -being called during rt_mutex_adjust_prio_chain(), in the context of -a process with a mutex enqueued. - -Instead of adding more complex conditions to decide when to directly -call __put_task_struct() and when to defer the call, unconditionally -resort to the deferred call on PREEMPT_RT to simplify the code. - -Fixes: 893cdaaa3977 ("sched: avoid false lockdep splat in put_task_struct()") -Suggested-by: Crystal Wood -Signed-off-by: Luis Claudio R. Goncalves -Signed-off-by: Peter Zijlstra (Intel) -Reviewed-by: Wander Lairson Costa -Reviewed-by: Valentin Schneider -Reviewed-by: Sebastian Andrzej Siewior -Link: https://lore.kernel.org/r/aGvTz5VaPFyj0pBV@uudg.org -Signed-off-by: Sasha Levin ---- - include/linux/sched/task.h | 27 ++++++++++----------------- - 1 file changed, 10 insertions(+), 17 deletions(-) - -diff --git a/include/linux/sched/task.h b/include/linux/sched/task.h -index ca1db4b92c32..58ce71715268 100644 ---- a/include/linux/sched/task.h -+++ b/include/linux/sched/task.h -@@ -135,24 +135,17 @@ static inline void put_task_struct(struct task_struct *t) - return; - - /* -- * In !RT, it is always safe to call __put_task_struct(). -- * Under RT, we can only call it in preemptible context. -- */ -- if (!IS_ENABLED(CONFIG_PREEMPT_RT) || preemptible()) { -- static DEFINE_WAIT_OVERRIDE_MAP(put_task_map, LD_WAIT_SLEEP); -- -- lock_map_acquire_try(&put_task_map); -- __put_task_struct(t); -- lock_map_release(&put_task_map); -- return; -- } -- -- /* -- * under PREEMPT_RT, we can't call put_task_struct -+ * Under PREEMPT_RT, we can't call __put_task_struct - * in atomic context because it will indirectly -- * acquire sleeping locks. -+ * acquire sleeping locks. The same is true if the -+ * current process has a mutex enqueued (blocked on -+ * a PI chain). -+ * -+ * In !RT, it is always safe to call __put_task_struct(). -+ * Though, in order to simplify the code, resort to the -+ * deferred call too. - * -- * call_rcu() will schedule delayed_put_task_struct_rcu() -+ * call_rcu() will schedule __put_task_struct_rcu_cb() - * to be called in process context. - * - * __put_task_struct() is called when -@@ -165,7 +158,7 @@ static inline void put_task_struct(struct task_struct *t) - * - * delayed_free_task() also uses ->rcu, but it is only called - * when it fails to fork a process. Therefore, there is no -- * way it can conflict with put_task_struct(). -+ * way it can conflict with __put_task_struct(). - */ - call_rcu(&t->rcu, __put_task_struct_rcu_cb); - } --- -2.39.5 - diff --git a/queue-6.16/series b/queue-6.16/series index 150b91d5d9..18748c92a6 100644 --- a/queue-6.16/series +++ b/queue-6.16/series @@ -87,7 +87,6 @@ revert-vmci-prevent-the-dispatching-of-uninitialized.patch powercap-dtpm_cpu-fix-null-pointer-dereference-in-ge.patch arm64-dts-ti-k3-am62p-verdin-add-sd_1-cd-pull-up.patch selftests-nolibc-correctly-report-errors-from-printf.patch -pwm-rockchip-round-period-duty-down-on-apply-up-on-g.patch usb-early-xhci-dbc-fix-early_ioremap-leak.patch tools-nolibc-avoid-false-positive-wmaybe-uninitializ.patch arm-dts-ti-omap-fixup-pinheader-typo.patch @@ -219,7 +218,6 @@ iommu-vt-d-do-not-wipe-out-the-page-table-nid-when-d.patch iommu-vt-d-fix-missing-pasid-in-dev-tlb-flush-with-c.patch iommu-arm-smmu-disable-prr-on-sm8250.patch xen-gntdev-remove-struct-gntdev_copy_batch-from-stac.patch -sched-do-not-call-__put_task_struct-on-rt-if-pi_bloc.patch tcp-call-tcp_measure_rcv_mss-for-ooo-packets.patch wifi-rtl8xxxu-fix-rx-skb-size-for-aggregation-disabl.patch wifi-rtw88-fix-macid-assigned-to-tdls-station.patch @@ -572,3 +570,6 @@ pptp-fix-pptp_xmit-error-path.patch smb-client-return-an-error-if-rdma_connect-does-not-.patch tools-power-turbostat-fix-bogus-syswatt-for-forked-p.patch tools-power-turbostat-fix-dmr-support.patch +nfsd-don-t-set-the-ctime-on-delegated-atime-updates.patch +nfsd-avoid-ref-leak-in-nfsd_open_local_fh.patch +sunrpc-fix-handling-of-server-side-tls-alerts.patch diff --git a/queue-6.16/sunrpc-fix-handling-of-server-side-tls-alerts.patch b/queue-6.16/sunrpc-fix-handling-of-server-side-tls-alerts.patch new file mode 100644 index 0000000000..99c5e053ae --- /dev/null +++ b/queue-6.16/sunrpc-fix-handling-of-server-side-tls-alerts.patch @@ -0,0 +1,114 @@ +From bee47cb026e762841f3faece47b51f985e215edb Mon Sep 17 00:00:00 2001 +From: Olga Kornievskaia +Date: Tue, 29 Jul 2025 12:40:20 -0400 +Subject: sunrpc: fix handling of server side tls alerts + +From: Olga Kornievskaia + +commit bee47cb026e762841f3faece47b51f985e215edb upstream. + +Scott Mayhew discovered a security exploit in NFS over TLS in +tls_alert_recv() due to its assumption it can read data from +the msg iterator's kvec.. + +kTLS implementation splits TLS non-data record payload between +the control message buffer (which includes the type such as TLS +aler or TLS cipher change) and the rest of the payload (say TLS +alert's level/description) which goes into the msg payload buffer. + +This patch proposes to rework how control messages are setup and +used by sock_recvmsg(). + +If no control message structure is setup, kTLS layer will read and +process TLS data record types. As soon as it encounters a TLS control +message, it would return an error. At that point, NFS can setup a +kvec backed msg buffer and read in the control message such as a +TLS alert. Msg iterator can advance the kvec pointer as a part of +the copy process thus we need to revert the iterator before calling +into the tls_alert_recv. + +Reported-by: Scott Mayhew +Fixes: 5e052dda121e ("SUNRPC: Recognize control messages in server-side TCP socket code") +Suggested-by: Trond Myklebust +Cc: stable@vger.kernel.org +Signed-off-by: Olga Kornievskaia +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + net/sunrpc/svcsock.c | 43 +++++++++++++++++++++++++++++++++++-------- + 1 file changed, 35 insertions(+), 8 deletions(-) + +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -257,20 +257,47 @@ svc_tcp_sock_process_cmsg(struct socket + } + + static int +-svc_tcp_sock_recv_cmsg(struct svc_sock *svsk, struct msghdr *msg) ++svc_tcp_sock_recv_cmsg(struct socket *sock, unsigned int *msg_flags) + { + union { + struct cmsghdr cmsg; + u8 buf[CMSG_SPACE(sizeof(u8))]; + } u; +- struct socket *sock = svsk->sk_sock; ++ u8 alert[2]; ++ struct kvec alert_kvec = { ++ .iov_base = alert, ++ .iov_len = sizeof(alert), ++ }; ++ struct msghdr msg = { ++ .msg_flags = *msg_flags, ++ .msg_control = &u, ++ .msg_controllen = sizeof(u), ++ }; ++ int ret; ++ ++ iov_iter_kvec(&msg.msg_iter, ITER_DEST, &alert_kvec, 1, ++ alert_kvec.iov_len); ++ ret = sock_recvmsg(sock, &msg, MSG_DONTWAIT); ++ if (ret > 0 && ++ tls_get_record_type(sock->sk, &u.cmsg) == TLS_RECORD_TYPE_ALERT) { ++ iov_iter_revert(&msg.msg_iter, ret); ++ ret = svc_tcp_sock_process_cmsg(sock, &msg, &u.cmsg, -EAGAIN); ++ } ++ return ret; ++} ++ ++static int ++svc_tcp_sock_recvmsg(struct svc_sock *svsk, struct msghdr *msg) ++{ + int ret; ++ struct socket *sock = svsk->sk_sock; + +- msg->msg_control = &u; +- msg->msg_controllen = sizeof(u); + ret = sock_recvmsg(sock, msg, MSG_DONTWAIT); +- if (unlikely(msg->msg_controllen != sizeof(u))) +- ret = svc_tcp_sock_process_cmsg(sock, msg, &u.cmsg, ret); ++ if (msg->msg_flags & MSG_CTRUNC) { ++ msg->msg_flags &= ~(MSG_CTRUNC | MSG_EOR); ++ if (ret == 0 || ret == -EIO) ++ ret = svc_tcp_sock_recv_cmsg(sock, &msg->msg_flags); ++ } + return ret; + } + +@@ -321,7 +348,7 @@ static ssize_t svc_tcp_read_msg(struct s + iov_iter_advance(&msg.msg_iter, seek); + buflen -= seek; + } +- len = svc_tcp_sock_recv_cmsg(svsk, &msg); ++ len = svc_tcp_sock_recvmsg(svsk, &msg); + if (len > 0) + svc_flush_bvec(bvec, len, seek); + +@@ -1018,7 +1045,7 @@ static ssize_t svc_tcp_read_marker(struc + iov.iov_base = ((char *)&svsk->sk_marker) + svsk->sk_tcplen; + iov.iov_len = want; + iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, want); +- len = svc_tcp_sock_recv_cmsg(svsk, &msg); ++ len = svc_tcp_sock_recvmsg(svsk, &msg); + if (len < 0) + return len; + svsk->sk_tcplen += len;