From: Greg Kroah-Hartman Date: Tue, 19 Nov 2024 12:10:28 +0000 (+0100) Subject: 6.6-stable patches X-Git-Tag: v6.12.1~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4d20c00155d89fed9d8cce10c2273a82feb7d3db;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: lib-buildid-fix-build-id-parsing-logic.patch media-dvbdev-fix-the-logic-when-dvb_dynamic_minors-is-not-set.patch nfsd-async-copy-result-needs-to-return-a-write-verifier.patch nfsd-initialize-copy-cp_clp-early-in-nfsd4_copy-for-use-by-trace-point.patch nfsd-initialize-struct-nfsd4_copy-earlier.patch nfsd-limit-the-number-of-concurrent-async-copy-operations.patch nfsd-never-decrement-pending_async_copies-on-error.patch --- diff --git a/queue-6.6/lib-buildid-fix-build-id-parsing-logic.patch b/queue-6.6/lib-buildid-fix-build-id-parsing-logic.patch new file mode 100644 index 00000000000..1924578eecc --- /dev/null +++ b/queue-6.6/lib-buildid-fix-build-id-parsing-logic.patch @@ -0,0 +1,37 @@ +From jolsa@kernel.org Tue Nov 19 12:59:14 2024 +From: Jiri Olsa +Date: Mon, 4 Nov 2024 18:52:55 +0100 +Subject: lib/buildid: Fix build ID parsing logic +To: stable@vger.kernel.org +Cc: Andrii Nakryiko , bpf@vger.kernel.org, Daniel Borkmann +Message-ID: <20241104175256.2327164-4-jolsa@kernel.org> + +From: Jiri Olsa + +The parse_build_id_buf does not account Elf32_Nhdr header size +when getting the build id data pointer and returns wrong build +id data as result. + +This is problem only for stable trees that merged c83a80d8b84f +fix, the upstream build id code was refactored and returns proper +build id. + +Acked-by: Andrii Nakryiko +Fixes: c83a80d8b84f ("lib/buildid: harden build ID parsing logic") +Signed-off-by: Jiri Olsa +Signed-off-by: Greg Kroah-Hartman +--- + lib/buildid.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/lib/buildid.c ++++ b/lib/buildid.c +@@ -40,7 +40,7 @@ static int parse_build_id_buf(unsigned c + name_sz == note_name_sz && + memcmp(nhdr + 1, note_name, note_name_sz) == 0 && + desc_sz > 0 && desc_sz <= BUILD_ID_SIZE_MAX) { +- data = note_start + note_off + ALIGN(note_name_sz, 4); ++ data = note_start + note_off + sizeof(Elf32_Nhdr) + ALIGN(note_name_sz, 4); + memcpy(build_id, data, desc_sz); + memset(build_id + desc_sz, 0, BUILD_ID_SIZE_MAX - desc_sz); + if (size) diff --git a/queue-6.6/media-dvbdev-fix-the-logic-when-dvb_dynamic_minors-is-not-set.patch b/queue-6.6/media-dvbdev-fix-the-logic-when-dvb_dynamic_minors-is-not-set.patch new file mode 100644 index 00000000000..bb813603872 --- /dev/null +++ b/queue-6.6/media-dvbdev-fix-the-logic-when-dvb_dynamic_minors-is-not-set.patch @@ -0,0 +1,57 @@ +From a4aebaf6e6efff548b01a3dc49b4b9074751c15b Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab +Date: Wed, 6 Nov 2024 21:50:55 +0100 +Subject: media: dvbdev: fix the logic when DVB_DYNAMIC_MINORS is not set + +From: Mauro Carvalho Chehab + +commit a4aebaf6e6efff548b01a3dc49b4b9074751c15b upstream. + +When CONFIG_DVB_DYNAMIC_MINORS, ret is not initialized, and a +semaphore is left at the wrong state, in case of errors. + +Make the code simpler and avoid mistakes by having just one error +check logic used weather DVB_DYNAMIC_MINORS is used or not. + +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/r/202410201717.ULWWdJv8-lkp@intel.com/ +Signed-off-by: Mauro Carvalho Chehab +Link: https://lore.kernel.org/r/9e067488d8935b8cf00959764a1fa5de85d65725.1730926254.git.mchehab+huawei@kernel.org +Cc: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/dvb-core/dvbdev.c | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +--- a/drivers/media/dvb-core/dvbdev.c ++++ b/drivers/media/dvb-core/dvbdev.c +@@ -530,6 +530,9 @@ int dvb_register_device(struct dvb_adapt + for (minor = 0; minor < MAX_DVB_MINORS; minor++) + if (!dvb_minors[minor]) + break; ++#else ++ minor = nums2minor(adap->num, type, id); ++#endif + if (minor >= MAX_DVB_MINORS) { + if (new_node) { + list_del(&new_node->list_head); +@@ -543,17 +546,7 @@ int dvb_register_device(struct dvb_adapt + mutex_unlock(&dvbdev_register_lock); + return -EINVAL; + } +-#else +- minor = nums2minor(adap->num, type, id); +- if (minor >= MAX_DVB_MINORS) { +- dvb_media_device_free(dvbdev); +- list_del(&dvbdev->list_head); +- kfree(dvbdev); +- *pdvbdev = NULL; +- mutex_unlock(&dvbdev_register_lock); +- return ret; +- } +-#endif ++ + dvbdev->minor = minor; + dvb_minors[minor] = dvb_device_get(dvbdev); + up_write(&minor_rwsem); diff --git a/queue-6.6/nfsd-async-copy-result-needs-to-return-a-write-verifier.patch b/queue-6.6/nfsd-async-copy-result-needs-to-return-a-write-verifier.patch new file mode 100644 index 00000000000..78ecaf10d59 --- /dev/null +++ b/queue-6.6/nfsd-async-copy-result-needs-to-return-a-write-verifier.patch @@ -0,0 +1,108 @@ +From stable+bounces-93834-greg=kroah.com@vger.kernel.org Mon Nov 18 22:14:33 2024 +From: cel@kernel.org +Date: Mon, 18 Nov 2024 16:14:10 -0500 +Subject: NFSD: Async COPY result needs to return a write verifier +To: +Cc: , Jeff Layton , Chuck Lever +Message-ID: <20241118211413.3756-3-cel@kernel.org> + +From: Chuck Lever + +[ Upstream commit 9ed666eba4e0a2bb8ffaa3739d830b64d4f2aaad ] + +Currently, when NFSD handles an asynchronous COPY, it returns a +zero write verifier, relying on the subsequent CB_OFFLOAD callback +to pass the write verifier and a stable_how4 value to the client. + +However, if the CB_OFFLOAD never arrives at the client (for example, +if a network partition occurs just as the server sends the +CB_OFFLOAD operation), the client will never receive this verifier. +Thus, if the client sends a follow-up COMMIT, there is no way for +the client to assess the COMMIT result. + +The usual recovery for a missing CB_OFFLOAD is for the client to +send an OFFLOAD_STATUS operation, but that operation does not carry +a write verifier in its result. Neither does it carry a stable_how4 +value, so the client /must/ send a COMMIT in this case -- which will +always fail because currently there's still no write verifier in the +COPY result. + +Thus the server needs to return a normal write verifier in its COPY +result even if the COPY operation is to be performed asynchronously. + +If the server recognizes the callback stateid in subsequent +OFFLOAD_STATUS operations, then obviously it has not restarted, and +the write verifier the client received in the COPY result is still +valid and can be used to assess a COMMIT of the copied data, if one +is needed. + +Reviewed-by: Jeff Layton +[ cel: adjusted to apply to origin/linux-6.6.y ] +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4proc.c | 23 ++++++++--------------- + 1 file changed, 8 insertions(+), 15 deletions(-) + +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -751,15 +751,6 @@ nfsd4_access(struct svc_rqst *rqstp, str + &access->ac_supported); + } + +-static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net) +-{ +- __be32 *verf = (__be32 *)verifier->data; +- +- BUILD_BUG_ON(2*sizeof(*verf) != sizeof(verifier->data)); +- +- nfsd_copy_write_verifier(verf, net_generic(net, nfsd_net_id)); +-} +- + static __be32 + nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) +@@ -1623,7 +1614,6 @@ static void nfsd4_init_copy_res(struct n + test_bit(NFSD4_COPY_F_COMMITTED, ©->cp_flags) ? + NFS_FILE_SYNC : NFS_UNSTABLE; + nfsd4_copy_set_sync(copy, sync); +- gen_boot_verifier(©->cp_res.wr_verifier, copy->cp_clp->net); + } + + static ssize_t _nfsd_copy_file_range(struct nfsd4_copy *copy, +@@ -1794,9 +1784,14 @@ static __be32 + nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) + { ++ struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); ++ struct nfsd4_copy *async_copy = NULL; + struct nfsd4_copy *copy = &u->copy; ++ struct nfsd42_write_res *result; + __be32 status; +- struct nfsd4_copy *async_copy = NULL; ++ ++ result = ©->cp_res; ++ nfsd_copy_write_verifier((__be32 *)&result->wr_verifier.data, nn); + + copy->cp_clp = cstate->clp; + if (nfsd4_ssc_is_inter(copy)) { +@@ -1816,8 +1811,6 @@ nfsd4_copy(struct svc_rqst *rqstp, struc + memcpy(©->fh, &cstate->current_fh.fh_handle, + sizeof(struct knfsd_fh)); + if (nfsd4_copy_is_async(copy)) { +- struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); +- + status = nfserrno(-ENOMEM); + async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); + if (!async_copy) +@@ -1829,8 +1822,8 @@ nfsd4_copy(struct svc_rqst *rqstp, struc + goto out_err; + if (!nfs4_init_copy_state(nn, copy)) + goto out_err; +- memcpy(©->cp_res.cb_stateid, ©->cp_stateid.cs_stid, +- sizeof(copy->cp_res.cb_stateid)); ++ memcpy(&result->cb_stateid, ©->cp_stateid.cs_stid, ++ sizeof(result->cb_stateid)); + dup_copy_fields(copy, async_copy); + async_copy->copy_task = kthread_create(nfsd4_do_async_copy, + async_copy, "%s", "copy thread"); diff --git a/queue-6.6/nfsd-initialize-copy-cp_clp-early-in-nfsd4_copy-for-use-by-trace-point.patch b/queue-6.6/nfsd-initialize-copy-cp_clp-early-in-nfsd4_copy-for-use-by-trace-point.patch new file mode 100644 index 00000000000..ae0b50e0910 --- /dev/null +++ b/queue-6.6/nfsd-initialize-copy-cp_clp-early-in-nfsd4_copy-for-use-by-trace-point.patch @@ -0,0 +1,41 @@ +From stable+bounces-93833-greg=kroah.com@vger.kernel.org Mon Nov 18 22:14:26 2024 +From: cel@kernel.org +Date: Mon, 18 Nov 2024 16:14:09 -0500 +Subject: NFSD: initialize copy->cp_clp early in nfsd4_copy for use by trace point +To: +Cc: , Jeff Layton , Dai Ngo , Chen Hanxiao +Message-ID: <20241118211413.3756-2-cel@kernel.org> + +From: Dai Ngo + +[ Upstream commit 15d1975b7279693d6f09398e0e2e31aca2310275 ] + +Prepare for adding server copy trace points. + +Signed-off-by: Dai Ngo +Tested-by: Chen Hanxiao +Stable-dep-of: 9ed666eba4e0 ("NFSD: Async COPY result needs to return a write verifier") +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4proc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -1798,6 +1798,7 @@ nfsd4_copy(struct svc_rqst *rqstp, struc + __be32 status; + struct nfsd4_copy *async_copy = NULL; + ++ copy->cp_clp = cstate->clp; + if (nfsd4_ssc_is_inter(copy)) { + if (!inter_copy_offload_enable || nfsd4_copy_is_sync(copy)) { + status = nfserr_notsupp; +@@ -1812,7 +1813,6 @@ nfsd4_copy(struct svc_rqst *rqstp, struc + return status; + } + +- copy->cp_clp = cstate->clp; + memcpy(©->fh, &cstate->current_fh.fh_handle, + sizeof(struct knfsd_fh)); + if (nfsd4_copy_is_async(copy)) { diff --git a/queue-6.6/nfsd-initialize-struct-nfsd4_copy-earlier.patch b/queue-6.6/nfsd-initialize-struct-nfsd4_copy-earlier.patch new file mode 100644 index 00000000000..4025ff84f5a --- /dev/null +++ b/queue-6.6/nfsd-initialize-struct-nfsd4_copy-earlier.patch @@ -0,0 +1,46 @@ +From stable+bounces-93836-greg=kroah.com@vger.kernel.org Mon Nov 18 22:14:38 2024 +From: cel@kernel.org +Date: Mon, 18 Nov 2024 16:14:12 -0500 +Subject: NFSD: Initialize struct nfsd4_copy earlier +To: +Cc: , Jeff Layton , Chuck Lever , Olga Kornievskaia +Message-ID: <20241118211413.3756-5-cel@kernel.org> + +From: Chuck Lever + +[ Upstream commit 63fab04cbd0f96191b6e5beedc3b643b01c15889 ] + +Ensure the refcount and async_copies fields are initialized early. +cleanup_async_copy() will reference these fields if an error occurs +in nfsd4_copy(). If they are not correctly initialized, at the very +least, a refcount underflow occurs. + +Reported-by: Olga Kornievskaia +Fixes: aadc3bbea163 ("NFSD: Limit the number of concurrent async COPY operations") +Reviewed-by: Jeff Layton +Tested-by: Olga Kornievskaia +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4proc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -1816,14 +1816,14 @@ nfsd4_copy(struct svc_rqst *rqstp, struc + if (!async_copy) + goto out_err; + async_copy->cp_nn = nn; ++ INIT_LIST_HEAD(&async_copy->copies); ++ refcount_set(&async_copy->refcount, 1); + /* Arbitrary cap on number of pending async copy operations */ + if (atomic_inc_return(&nn->pending_async_copies) > + (int)rqstp->rq_pool->sp_nrthreads) { + atomic_dec(&nn->pending_async_copies); + goto out_err; + } +- INIT_LIST_HEAD(&async_copy->copies); +- refcount_set(&async_copy->refcount, 1); + async_copy->cp_src = kmalloc(sizeof(*async_copy->cp_src), GFP_KERNEL); + if (!async_copy->cp_src) + goto out_err; diff --git a/queue-6.6/nfsd-limit-the-number-of-concurrent-async-copy-operations.patch b/queue-6.6/nfsd-limit-the-number-of-concurrent-async-copy-operations.patch new file mode 100644 index 00000000000..ed8093b5dac --- /dev/null +++ b/queue-6.6/nfsd-limit-the-number-of-concurrent-async-copy-operations.patch @@ -0,0 +1,108 @@ +From stable+bounces-93835-greg=kroah.com@vger.kernel.org Mon Nov 18 22:14:35 2024 +From: cel@kernel.org +Date: Mon, 18 Nov 2024 16:14:11 -0500 +Subject: NFSD: Limit the number of concurrent async COPY operations +To: +Cc: , Jeff Layton , Chuck Lever +Message-ID: <20241118211413.3756-4-cel@kernel.org> + +From: Chuck Lever + +[ Upstream commit aadc3bbea163b6caaaebfdd2b6c4667fbc726752 ] + +Nothing appears to limit the number of concurrent async COPY +operations that clients can start. In addition, AFAICT each async +COPY can copy an unlimited number of 4MB chunks, so can run for a +long time. Thus IMO async COPY can become a DoS vector. + +Add a restriction mechanism that bounds the number of concurrent +background COPY operations. Start simple and try to be fair -- this +patch implements a per-namespace limit. + +An async COPY request that occurs while this limit is exceeded gets +NFS4ERR_DELAY. The requesting client can choose to send the request +again after a delay or fall back to a traditional read/write style +copy. + +If there is need to make the mechanism more sophisticated, we can +visit that in future patches. + +Cc: stable@vger.kernel.org +Reviewed-by: Jeff Layton +Link: https://nvd.nist.gov/vuln/detail/CVE-2024-49974 +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/netns.h | 1 + + fs/nfsd/nfs4proc.c | 11 +++++++++-- + fs/nfsd/nfs4state.c | 1 + + fs/nfsd/xdr4.h | 1 + + 4 files changed, 12 insertions(+), 2 deletions(-) + +--- a/fs/nfsd/netns.h ++++ b/fs/nfsd/netns.h +@@ -153,6 +153,7 @@ struct nfsd_net { + u32 s2s_cp_cl_id; + struct idr s2s_cp_stateids; + spinlock_t s2s_cp_lock; ++ atomic_t pending_async_copies; + + /* + * Version information +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -1273,6 +1273,7 @@ static void nfs4_put_copy(struct nfsd4_c + { + if (!refcount_dec_and_test(©->refcount)) + return; ++ atomic_dec(©->cp_nn->pending_async_copies); + kfree(copy->cp_src); + kfree(copy); + } +@@ -1811,10 +1812,16 @@ nfsd4_copy(struct svc_rqst *rqstp, struc + memcpy(©->fh, &cstate->current_fh.fh_handle, + sizeof(struct knfsd_fh)); + if (nfsd4_copy_is_async(copy)) { +- status = nfserrno(-ENOMEM); + async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL); + if (!async_copy) + goto out_err; ++ async_copy->cp_nn = nn; ++ /* Arbitrary cap on number of pending async copy operations */ ++ if (atomic_inc_return(&nn->pending_async_copies) > ++ (int)rqstp->rq_pool->sp_nrthreads) { ++ atomic_dec(&nn->pending_async_copies); ++ goto out_err; ++ } + INIT_LIST_HEAD(&async_copy->copies); + refcount_set(&async_copy->refcount, 1); + async_copy->cp_src = kmalloc(sizeof(*async_copy->cp_src), GFP_KERNEL); +@@ -1853,7 +1860,7 @@ out_err: + } + if (async_copy) + cleanup_async_copy(async_copy); +- status = nfserrno(-ENOMEM); ++ status = nfserr_jukebox; + goto out; + } + +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -8142,6 +8142,7 @@ static int nfs4_state_create_net(struct + spin_lock_init(&nn->client_lock); + spin_lock_init(&nn->s2s_cp_lock); + idr_init(&nn->s2s_cp_stateids); ++ atomic_set(&nn->pending_async_copies, 0); + + spin_lock_init(&nn->blocked_locks_lock); + INIT_LIST_HEAD(&nn->blocked_locks_lru); +--- a/fs/nfsd/xdr4.h ++++ b/fs/nfsd/xdr4.h +@@ -574,6 +574,7 @@ struct nfsd4_copy { + struct nfsd4_ssc_umount_item *ss_nsui; + struct nfs_fh c_fh; + nfs4_stateid stateid; ++ struct nfsd_net *cp_nn; + }; + + static inline void nfsd4_copy_set_sync(struct nfsd4_copy *copy, bool sync) diff --git a/queue-6.6/nfsd-never-decrement-pending_async_copies-on-error.patch b/queue-6.6/nfsd-never-decrement-pending_async_copies-on-error.patch new file mode 100644 index 00000000000..4d6edc2e8aa --- /dev/null +++ b/queue-6.6/nfsd-never-decrement-pending_async_copies-on-error.patch @@ -0,0 +1,37 @@ +From stable+bounces-93837-greg=kroah.com@vger.kernel.org Mon Nov 18 22:14:42 2024 +From: cel@kernel.org +Date: Mon, 18 Nov 2024 16:14:13 -0500 +Subject: NFSD: Never decrement pending_async_copies on error +To: +Cc: , Jeff Layton , Chuck Lever , Olga Kornievskaia +Message-ID: <20241118211413.3756-6-cel@kernel.org> + +From: Chuck Lever + +[ Upstream commit 8286f8b622990194207df9ab852e0f87c60d35e9 ] + +The error flow in nfsd4_copy() calls cleanup_async_copy(), which +already decrements nn->pending_async_copies. + +Reported-by: Olga Kornievskaia +Fixes: aadc3bbea163 ("NFSD: Limit the number of concurrent async COPY operations") +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + fs/nfsd/nfs4proc.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/fs/nfsd/nfs4proc.c ++++ b/fs/nfsd/nfs4proc.c +@@ -1820,10 +1820,8 @@ nfsd4_copy(struct svc_rqst *rqstp, struc + refcount_set(&async_copy->refcount, 1); + /* Arbitrary cap on number of pending async copy operations */ + if (atomic_inc_return(&nn->pending_async_copies) > +- (int)rqstp->rq_pool->sp_nrthreads) { +- atomic_dec(&nn->pending_async_copies); ++ (int)rqstp->rq_pool->sp_nrthreads) + goto out_err; +- } + async_copy->cp_src = kmalloc(sizeof(*async_copy->cp_src), GFP_KERNEL); + if (!async_copy->cp_src) + goto out_err; diff --git a/queue-6.6/series b/queue-6.6/series index 9368f5a1eca..8b94def5fff 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -56,3 +56,10 @@ mm-damon-core-implement-scheme-specific-apply-interv.patch mm-damon-core-handle-zero-aggregation-ops_update-int.patch staging-vchiq_arm-get-the-rid-off-struct-vchiq_2835_.patch staging-vchiq_arm-use-devm_kzalloc-for-vchiq_arm_sta.patch +lib-buildid-fix-build-id-parsing-logic.patch +media-dvbdev-fix-the-logic-when-dvb_dynamic_minors-is-not-set.patch +nfsd-initialize-copy-cp_clp-early-in-nfsd4_copy-for-use-by-trace-point.patch +nfsd-async-copy-result-needs-to-return-a-write-verifier.patch +nfsd-limit-the-number-of-concurrent-async-copy-operations.patch +nfsd-initialize-struct-nfsd4_copy-earlier.patch +nfsd-never-decrement-pending_async_copies-on-error.patch