From: Sasha Levin Date: Sat, 29 Jun 2024 11:50:01 +0000 (-0400) Subject: Fixes for 5.10 X-Git-Tag: v4.19.317~128 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9ab28b7b2a44b65f27e30ebd932b0373d444b867;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/asoc-fsl-asoc-card-set-priv-pdev-before-using-it.patch b/queue-5.10/asoc-fsl-asoc-card-set-priv-pdev-before-using-it.patch new file mode 100644 index 00000000000..f4b4a748b2f --- /dev/null +++ b/queue-5.10/asoc-fsl-asoc-card-set-priv-pdev-before-using-it.patch @@ -0,0 +1,54 @@ +From e89fb31552450e31afb1ee0f1f9ac17f23a92d60 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Jun 2024 15:25:03 +0200 +Subject: ASoC: fsl-asoc-card: set priv->pdev before using it + +From: Elinor Montmasson + +[ Upstream commit 90f3feb24172185f1832636264943e8b5e289245 ] + +priv->pdev pointer was set after being used in +fsl_asoc_card_audmux_init(). +Move this assignment at the start of the probe function, so +sub-functions can correctly use pdev through priv. + +fsl_asoc_card_audmux_init() dereferences priv->pdev to get access to the +dev struct, used with dev_err macros. +As priv is zero-initialised, there would be a NULL pointer dereference. +Note that if priv->dev is dereferenced before assignment but never used, +for example if there is no error to be printed, the driver won't crash +probably due to compiler optimisations. + +Fixes: 708b4351f08c ("ASoC: fsl: Add Freescale Generic ASoC Sound Card with ASRC support") +Signed-off-by: Elinor Montmasson +Link: https://patch.msgid.link/20240620132511.4291-2-elinor.montmasson@savoirfairelinux.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl-asoc-card.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c +index 9a756d0a60320..c876f111d8b03 100644 +--- a/sound/soc/fsl/fsl-asoc-card.c ++++ b/sound/soc/fsl/fsl-asoc-card.c +@@ -538,6 +538,8 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) + if (!priv) + return -ENOMEM; + ++ priv->pdev = pdev; ++ + cpu_np = of_parse_phandle(np, "audio-cpu", 0); + /* Give a chance to old DT binding */ + if (!cpu_np) +@@ -718,7 +720,6 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) + } + + /* Initialize sound card */ +- priv->pdev = pdev; + priv->card.dev = &pdev->dev; + priv->card.owner = THIS_MODULE; + ret = snd_soc_of_parse_card_name(&priv->card, "model"); +-- +2.43.0 + diff --git a/queue-5.10/net-dsa-microchip-fix-initial-port-flush-problem.patch b/queue-5.10/net-dsa-microchip-fix-initial-port-flush-problem.patch new file mode 100644 index 00000000000..3fc2eead870 --- /dev/null +++ b/queue-5.10/net-dsa-microchip-fix-initial-port-flush-problem.patch @@ -0,0 +1,49 @@ +From a46841e51a942dde39b03c0976ffe1244da7c714 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Jun 2024 17:16:42 -0700 +Subject: net: dsa: microchip: fix initial port flush problem + +From: Tristram Ha + +[ Upstream commit ad53f5f54f351e967128edbc431f0f26427172cf ] + +The very first flush in any port will flush all learned addresses in all +ports. This can be observed by unplugging the cable from one port while +additional ports are connected and dumping the fdb entries. + +This problem is caused by the initially wrong value programmed to the +REG_SW_LUE_CTRL_1 register. Setting SW_FLUSH_STP_TABLE and +SW_FLUSH_MSTP_TABLE bits does not have an immediate effect. It is when +ksz9477_flush_dyn_mac_table() is called then the SW_FLUSH_STP_TABLE bit +takes effect and flushes all learned entries. After that call both bits +are reset and so the next port flush will not cause such problem again. + +Fixes: b987e98e50ab ("dsa: add DSA switch driver for Microchip KSZ9477") +Signed-off-by: Tristram Ha +Link: https://patch.msgid.link/1718756202-2731-1-git-send-email-Tristram.Ha@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/microchip/ksz9477.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c +index f42f2f4e4b60e..535b64155320a 100644 +--- a/drivers/net/dsa/microchip/ksz9477.c ++++ b/drivers/net/dsa/microchip/ksz9477.c +@@ -206,10 +206,8 @@ static int ksz9477_reset_switch(struct ksz_device *dev) + SPI_AUTO_EDGE_DETECTION, 0); + + /* default configuration */ +- ksz_read8(dev, REG_SW_LUE_CTRL_1, &data8); +- data8 = SW_AGING_ENABLE | SW_LINK_AUTO_AGING | +- SW_SRC_ADDR_FILTER | SW_FLUSH_STP_TABLE | SW_FLUSH_MSTP_TABLE; +- ksz_write8(dev, REG_SW_LUE_CTRL_1, data8); ++ ksz_write8(dev, REG_SW_LUE_CTRL_1, ++ SW_AGING_ENABLE | SW_LINK_AUTO_AGING | SW_SRC_ADDR_FILTER); + + /* disable interrupts */ + ksz_write32(dev, REG_SW_INT_MASK__4, SWITCH_INT_MASK); +-- +2.43.0 + diff --git a/queue-5.10/net-phy-micrel-add-microchip-ksz-9477-to-the-device-.patch b/queue-5.10/net-phy-micrel-add-microchip-ksz-9477-to-the-device-.patch new file mode 100644 index 00000000000..02b3d98b3ca --- /dev/null +++ b/queue-5.10/net-phy-micrel-add-microchip-ksz-9477-to-the-device-.patch @@ -0,0 +1,36 @@ +From 2d6e03c05e9c8b4728851cacc83a2fcaee8257c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Jun 2024 16:43:20 +0200 +Subject: net: phy: micrel: add Microchip KSZ 9477 to the device table + +From: Enguerrand de Ribaucourt + +[ Upstream commit 54a4e5c16382e871c01dd82b47e930fdce30406b ] + +PHY_ID_KSZ9477 was supported but not added to the device table passed to +MODULE_DEVICE_TABLE. + +Fixes: fc3973a1fa09 ("phy: micrel: add Microchip KSZ 9477 Switch PHY support") +Signed-off-by: Enguerrand de Ribaucourt +Reviewed-by: Andrew Lunn +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + drivers/net/phy/micrel.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c +index 2b7616f161d69..b68682006c06c 100644 +--- a/drivers/net/phy/micrel.c ++++ b/drivers/net/phy/micrel.c +@@ -1410,6 +1410,7 @@ static struct mdio_device_id __maybe_unused micrel_tbl[] = { + { PHY_ID_KSZ8081, MICREL_PHY_ID_MASK }, + { PHY_ID_KSZ8873MLL, MICREL_PHY_ID_MASK }, + { PHY_ID_KSZ886X, MICREL_PHY_ID_MASK }, ++ { PHY_ID_KSZ9477, MICREL_PHY_ID_MASK }, + { PHY_ID_LAN8814, MICREL_PHY_ID_MASK }, + { } + }; +-- +2.43.0 + diff --git a/queue-5.10/netfilter-nf_tables-fully-validate-nft_data_value-on.patch b/queue-5.10/netfilter-nf_tables-fully-validate-nft_data_value-on.patch new file mode 100644 index 00000000000..c6349dbe067 --- /dev/null +++ b/queue-5.10/netfilter-nf_tables-fully-validate-nft_data_value-on.patch @@ -0,0 +1,92 @@ +From d0c60a5b71505b43294d3c581f2e6209560927b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Jun 2024 23:15:38 +0200 +Subject: netfilter: nf_tables: fully validate NFT_DATA_VALUE on store to data + registers + +From: Pablo Neira Ayuso + +[ Upstream commit 7931d32955e09d0a11b1fe0b6aac1bfa061c005c ] + +register store validation for NFT_DATA_VALUE is conditional, however, +the datatype is always either NFT_DATA_VALUE or NFT_DATA_VERDICT. This +only requires a new helper function to infer the register type from the +set datatype so this conditional check can be removed. Otherwise, +pointer to chain object can be leaked through the registers. + +Fixes: 96518518cc41 ("netfilter: add nftables") +Reported-by: Linus Torvalds +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables.h | 5 +++++ + net/netfilter/nf_tables_api.c | 8 ++++---- + net/netfilter/nft_lookup.c | 3 ++- + 3 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index ab8d84775ca87..2b99ee1303d92 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -490,6 +490,11 @@ static inline void *nft_set_priv(const struct nft_set *set) + return (void *)set->data; + } + ++static inline enum nft_data_types nft_set_datatype(const struct nft_set *set) ++{ ++ return set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE; ++} ++ + static inline bool nft_set_gc_is_pending(const struct nft_set *s) + { + return refcount_read(&s->refs) != 1; +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 754278b857068..f4bbddfbbc247 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -4990,8 +4990,7 @@ static int nf_tables_fill_setelem(struct sk_buff *skb, + + if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA) && + nft_data_dump(skb, NFTA_SET_ELEM_DATA, nft_set_ext_data(ext), +- set->dtype == NFT_DATA_VERDICT ? NFT_DATA_VERDICT : NFT_DATA_VALUE, +- set->dlen) < 0) ++ nft_set_datatype(set), set->dlen) < 0) + goto nla_put_failure; + + if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPR) && +@@ -9337,6 +9336,9 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, + + return 0; + default: ++ if (type != NFT_DATA_VALUE) ++ return -EINVAL; ++ + if (reg < NFT_REG_1 * NFT_REG_SIZE / NFT_REG32_SIZE) + return -EINVAL; + if (len == 0) +@@ -9345,8 +9347,6 @@ static int nft_validate_register_store(const struct nft_ctx *ctx, + sizeof_field(struct nft_regs, data)) + return -ERANGE; + +- if (data != NULL && type != NFT_DATA_VALUE) +- return -EINVAL; + return 0; + } + } +diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c +index 8bc008ff00cb7..d2f8131edaf14 100644 +--- a/net/netfilter/nft_lookup.c ++++ b/net/netfilter/nft_lookup.c +@@ -101,7 +101,8 @@ static int nft_lookup_init(const struct nft_ctx *ctx, + return -EINVAL; + + err = nft_parse_register_store(ctx, tb[NFTA_LOOKUP_DREG], +- &priv->dreg, NULL, set->dtype, ++ &priv->dreg, NULL, ++ nft_set_datatype(set), + set->dlen); + if (err < 0) + return err; +-- +2.43.0 + diff --git a/queue-5.10/nfsd-hold-a-lighter-weight-client-reference-over-cb_.patch b/queue-5.10/nfsd-hold-a-lighter-weight-client-reference-over-cb_.patch new file mode 100644 index 00000000000..c1ab9710572 --- /dev/null +++ b/queue-5.10/nfsd-hold-a-lighter-weight-client-reference-over-cb_.patch @@ -0,0 +1,65 @@ +From aaec4bd435d4b8a88c96d4a52e2f563e27668a8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Jun 2024 14:27:45 -0400 +Subject: nfsd: hold a lighter-weight client reference over CB_RECALL_ANY + +From: Jeff Layton + +[ Upstream commit 10396f4df8b75ff6ab0aa2cd74296565466f2c8d ] + +Currently the CB_RECALL_ANY job takes a cl_rpc_users reference to the +client. While a callback job is technically an RPC that counter is +really more for client-driven RPCs, and this has the effect of +preventing the client from being unhashed until the callback completes. + +If nfsd decides to send a CB_RECALL_ANY just as the client reboots, we +can end up in a situation where the callback can't complete on the (now +dead) callback channel, but the new client can't connect because the old +client can't be unhashed. This usually manifests as a NFS4ERR_DELAY +return on the CREATE_SESSION operation. + +The job is only holding a reference to the client so it can clear a flag +after the RPC completes. Fix this by having CB_RECALL_ANY instead hold a +reference to the cl_nfsdfs.cl_ref. Typically we only take that sort of +reference when dealing with the nfsdfs info files, but it should work +appropriately here to ensure that the nfs4_client doesn't disappear. + +Fixes: 44df6f439a17 ("NFSD: add delegation reaper to react to low memory condition") +Reported-by: Vladimir Benes +Signed-off-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/nfs4state.c | 7 ++----- + 1 file changed, 2 insertions(+), 5 deletions(-) + +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index 228560f3fd0e0..8e84ddccce4bf 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -2888,12 +2888,9 @@ static void + nfsd4_cb_recall_any_release(struct nfsd4_callback *cb) + { + struct nfs4_client *clp = cb->cb_clp; +- struct nfsd_net *nn = net_generic(clp->net, nfsd_net_id); + +- spin_lock(&nn->client_lock); + clear_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags); +- put_client_renew_locked(clp); +- spin_unlock(&nn->client_lock); ++ drop_client(clp); + } + + static const struct nfsd4_callback_ops nfsd4_cb_recall_any_ops = { +@@ -6230,7 +6227,7 @@ deleg_reaper(struct nfsd_net *nn) + list_add(&clp->cl_ra_cblist, &cblist); + + /* release in nfsd4_cb_recall_any_release */ +- atomic_inc(&clp->cl_rpc_users); ++ kref_get(&clp->cl_nfsdfs.cl_ref); + set_bit(NFSD4_CLIENT_CB_RECALL_ANY, &clp->cl_flags); + clp->cl_ra_time = ktime_get_boottime_seconds(); + } +-- +2.43.0 + diff --git a/queue-5.10/parisc-use-correct-compat-recv-recvfrom-syscalls.patch b/queue-5.10/parisc-use-correct-compat-recv-recvfrom-syscalls.patch new file mode 100644 index 00000000000..5d211616e3d --- /dev/null +++ b/queue-5.10/parisc-use-correct-compat-recv-recvfrom-syscalls.patch @@ -0,0 +1,48 @@ +From 9073495dda42c76ad1376e2d80a610596f802ecd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Jun 2024 14:27:55 +0200 +Subject: parisc: use correct compat recv/recvfrom syscalls + +From: Arnd Bergmann + +[ Upstream commit 20a50787349fadf66ac5c48f62e58d753878d2bb ] + +Johannes missed parisc back when he introduced the compat version +of these syscalls, so receiving cmsg messages that require a compat +conversion is still broken. + +Use the correct calls like the other architectures do. + +Fixes: 1dacc76d0014 ("net/compat/wext: send different messages to compat tasks") +Acked-by: Helge Deller +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/parisc/kernel/syscalls/syscall.tbl | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl +index dfe9254ee74b6..e9c70f9a2f505 100644 +--- a/arch/parisc/kernel/syscalls/syscall.tbl ++++ b/arch/parisc/kernel/syscalls/syscall.tbl +@@ -108,7 +108,7 @@ + 95 common fchown sys_fchown + 96 common getpriority sys_getpriority + 97 common setpriority sys_setpriority +-98 common recv sys_recv ++98 common recv sys_recv compat_sys_recv + 99 common statfs sys_statfs compat_sys_statfs + 100 common fstatfs sys_fstatfs compat_sys_fstatfs + 101 common stat64 sys_stat64 +@@ -135,7 +135,7 @@ + 120 common clone sys_clone_wrapper + 121 common setdomainname sys_setdomainname + 122 common sendfile sys_sendfile compat_sys_sendfile +-123 common recvfrom sys_recvfrom ++123 common recvfrom sys_recvfrom compat_sys_recvfrom + 124 32 adjtimex sys_adjtimex_time32 + 124 64 adjtimex sys_adjtimex + 125 common mprotect sys_mprotect +-- +2.43.0 + diff --git a/queue-5.10/series b/queue-5.10/series index 394321e3c16..4c8b5ad5a6e 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -263,3 +263,19 @@ pinctrl-rockchip-use-dedicated-pinctrl-type-for-rk33.patch pinctrl-rockchip-fix-pinmux-reset-in-rockchip_pmx_se.patch drm-amdgpu-fix-ubsan-warning-in-kv_dpm.c.patch netfilter-nf_tables-validate-family-when-identifying.patch +sunrpc-fix-null-pointer-dereference-in-svc_rqst_free.patch +sunrpc-fix-a-null-pointer-deref-in-trace_svc_stats_l.patch +sunrpc-fix-svcxdr_init_decode-s-end-of-buffer-calcul.patch +sunrpc-fix-svcxdr_init_encode-s-buflen-calculation.patch +nfsd-hold-a-lighter-weight-client-reference-over-cb_.patch +asoc-fsl-asoc-card-set-priv-pdev-before-using-it.patch +net-dsa-microchip-fix-initial-port-flush-problem.patch +net-phy-micrel-add-microchip-ksz-9477-to-the-device-.patch +xdp-move-the-rxq_info.mem-clearing-to-unreg_mem_mode.patch +xdp-allow-registering-memory-model-without-rxq-refer.patch +xdp-remove-warn-from-__xdp_reg_mem_model.patch +sparc-fix-old-compat_sys_select.patch +sparc-fix-compat-recv-recvfrom-syscalls.patch +parisc-use-correct-compat-recv-recvfrom-syscalls.patch +netfilter-nf_tables-fully-validate-nft_data_value-on.patch +tracing-net_sched-null-pointer-dereference-in-perf_t.patch diff --git a/queue-5.10/sparc-fix-compat-recv-recvfrom-syscalls.patch b/queue-5.10/sparc-fix-compat-recv-recvfrom-syscalls.patch new file mode 100644 index 00000000000..f14328e457a --- /dev/null +++ b/queue-5.10/sparc-fix-compat-recv-recvfrom-syscalls.patch @@ -0,0 +1,279 @@ +From dfb5a27727913e6f1c4fab4416bf5707abd01b83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Jun 2024 12:49:39 +0200 +Subject: sparc: fix compat recv/recvfrom syscalls + +From: Arnd Bergmann + +[ Upstream commit d6fbd26fb872ec518d25433a12e8ce8163e20909 ] + +sparc has the wrong compat version of recv() and recvfrom() for both the +direct syscalls and socketcall(). + +The direct syscalls just need to use the compat version. For socketcall, +the same thing could be done, but it seems better to completely remove +the custom assembler code for it and just use the same implementation that +everyone else has. + +Fixes: 1dacc76d0014 ("net/compat/wext: send different messages to compat tasks") +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/sparc/kernel/sys32.S | 221 ------------------------- + arch/sparc/kernel/syscalls/syscall.tbl | 4 +- + 2 files changed, 2 insertions(+), 223 deletions(-) + +diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S +index a45f0f31fe51a..a3d308f2043e5 100644 +--- a/arch/sparc/kernel/sys32.S ++++ b/arch/sparc/kernel/sys32.S +@@ -18,224 +18,3 @@ sys32_mmap2: + sethi %hi(sys_mmap), %g1 + jmpl %g1 + %lo(sys_mmap), %g0 + sllx %o5, 12, %o5 +- +- .align 32 +- .globl sys32_socketcall +-sys32_socketcall: /* %o0=call, %o1=args */ +- cmp %o0, 1 +- bl,pn %xcc, do_einval +- cmp %o0, 18 +- bg,pn %xcc, do_einval +- sub %o0, 1, %o0 +- sllx %o0, 5, %o0 +- sethi %hi(__socketcall_table_begin), %g2 +- or %g2, %lo(__socketcall_table_begin), %g2 +- jmpl %g2 + %o0, %g0 +- nop +-do_einval: +- retl +- mov -EINVAL, %o0 +- +- .align 32 +-__socketcall_table_begin: +- +- /* Each entry is exactly 32 bytes. */ +-do_sys_socket: /* sys_socket(int, int, int) */ +-1: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_socket), %g1 +-2: ldswa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_socket), %g0 +-3: ldswa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_bind: /* sys_bind(int fd, struct sockaddr *, int) */ +-4: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_bind), %g1 +-5: ldswa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_bind), %g0 +-6: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_connect: /* sys_connect(int, struct sockaddr *, int) */ +-7: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_connect), %g1 +-8: ldswa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_connect), %g0 +-9: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_listen: /* sys_listen(int, int) */ +-10: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_listen), %g1 +- jmpl %g1 + %lo(sys_listen), %g0 +-11: ldswa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +- nop +-do_sys_accept: /* sys_accept(int, struct sockaddr *, int *) */ +-12: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_accept), %g1 +-13: lduwa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_accept), %g0 +-14: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_getsockname: /* sys_getsockname(int, struct sockaddr *, int *) */ +-15: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_getsockname), %g1 +-16: lduwa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_getsockname), %g0 +-17: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_getpeername: /* sys_getpeername(int, struct sockaddr *, int *) */ +-18: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_getpeername), %g1 +-19: lduwa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(sys_getpeername), %g0 +-20: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_socketpair: /* sys_socketpair(int, int, int, int *) */ +-21: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_socketpair), %g1 +-22: ldswa [%o1 + 0x8] %asi, %o2 +-23: lduwa [%o1 + 0xc] %asi, %o3 +- jmpl %g1 + %lo(sys_socketpair), %g0 +-24: ldswa [%o1 + 0x4] %asi, %o1 +- nop +- nop +-do_sys_send: /* sys_send(int, void *, size_t, unsigned int) */ +-25: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_send), %g1 +-26: lduwa [%o1 + 0x8] %asi, %o2 +-27: lduwa [%o1 + 0xc] %asi, %o3 +- jmpl %g1 + %lo(sys_send), %g0 +-28: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +-do_sys_recv: /* sys_recv(int, void *, size_t, unsigned int) */ +-29: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_recv), %g1 +-30: lduwa [%o1 + 0x8] %asi, %o2 +-31: lduwa [%o1 + 0xc] %asi, %o3 +- jmpl %g1 + %lo(sys_recv), %g0 +-32: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +-do_sys_sendto: /* sys_sendto(int, u32, compat_size_t, unsigned int, u32, int) */ +-33: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_sendto), %g1 +-34: lduwa [%o1 + 0x8] %asi, %o2 +-35: lduwa [%o1 + 0xc] %asi, %o3 +-36: lduwa [%o1 + 0x10] %asi, %o4 +-37: ldswa [%o1 + 0x14] %asi, %o5 +- jmpl %g1 + %lo(sys_sendto), %g0 +-38: lduwa [%o1 + 0x4] %asi, %o1 +-do_sys_recvfrom: /* sys_recvfrom(int, u32, compat_size_t, unsigned int, u32, u32) */ +-39: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_recvfrom), %g1 +-40: lduwa [%o1 + 0x8] %asi, %o2 +-41: lduwa [%o1 + 0xc] %asi, %o3 +-42: lduwa [%o1 + 0x10] %asi, %o4 +-43: lduwa [%o1 + 0x14] %asi, %o5 +- jmpl %g1 + %lo(sys_recvfrom), %g0 +-44: lduwa [%o1 + 0x4] %asi, %o1 +-do_sys_shutdown: /* sys_shutdown(int, int) */ +-45: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_shutdown), %g1 +- jmpl %g1 + %lo(sys_shutdown), %g0 +-46: ldswa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +- nop +-do_sys_setsockopt: /* sys_setsockopt(int, int, int, char *, int) */ +-47: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_setsockopt), %g1 +-48: ldswa [%o1 + 0x8] %asi, %o2 +-49: lduwa [%o1 + 0xc] %asi, %o3 +-50: ldswa [%o1 + 0x10] %asi, %o4 +- jmpl %g1 + %lo(sys_setsockopt), %g0 +-51: ldswa [%o1 + 0x4] %asi, %o1 +- nop +-do_sys_getsockopt: /* sys_getsockopt(int, int, int, u32, u32) */ +-52: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_getsockopt), %g1 +-53: ldswa [%o1 + 0x8] %asi, %o2 +-54: lduwa [%o1 + 0xc] %asi, %o3 +-55: lduwa [%o1 + 0x10] %asi, %o4 +- jmpl %g1 + %lo(sys_getsockopt), %g0 +-56: ldswa [%o1 + 0x4] %asi, %o1 +- nop +-do_sys_sendmsg: /* compat_sys_sendmsg(int, struct compat_msghdr *, unsigned int) */ +-57: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(compat_sys_sendmsg), %g1 +-58: lduwa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(compat_sys_sendmsg), %g0 +-59: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_recvmsg: /* compat_sys_recvmsg(int, struct compat_msghdr *, unsigned int) */ +-60: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(compat_sys_recvmsg), %g1 +-61: lduwa [%o1 + 0x8] %asi, %o2 +- jmpl %g1 + %lo(compat_sys_recvmsg), %g0 +-62: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- nop +-do_sys_accept4: /* sys_accept4(int, struct sockaddr *, int *, int) */ +-63: ldswa [%o1 + 0x0] %asi, %o0 +- sethi %hi(sys_accept4), %g1 +-64: lduwa [%o1 + 0x8] %asi, %o2 +-65: ldswa [%o1 + 0xc] %asi, %o3 +- jmpl %g1 + %lo(sys_accept4), %g0 +-66: lduwa [%o1 + 0x4] %asi, %o1 +- nop +- nop +- +- .section __ex_table,"a" +- .align 4 +- .word 1b, __retl_efault, 2b, __retl_efault +- .word 3b, __retl_efault, 4b, __retl_efault +- .word 5b, __retl_efault, 6b, __retl_efault +- .word 7b, __retl_efault, 8b, __retl_efault +- .word 9b, __retl_efault, 10b, __retl_efault +- .word 11b, __retl_efault, 12b, __retl_efault +- .word 13b, __retl_efault, 14b, __retl_efault +- .word 15b, __retl_efault, 16b, __retl_efault +- .word 17b, __retl_efault, 18b, __retl_efault +- .word 19b, __retl_efault, 20b, __retl_efault +- .word 21b, __retl_efault, 22b, __retl_efault +- .word 23b, __retl_efault, 24b, __retl_efault +- .word 25b, __retl_efault, 26b, __retl_efault +- .word 27b, __retl_efault, 28b, __retl_efault +- .word 29b, __retl_efault, 30b, __retl_efault +- .word 31b, __retl_efault, 32b, __retl_efault +- .word 33b, __retl_efault, 34b, __retl_efault +- .word 35b, __retl_efault, 36b, __retl_efault +- .word 37b, __retl_efault, 38b, __retl_efault +- .word 39b, __retl_efault, 40b, __retl_efault +- .word 41b, __retl_efault, 42b, __retl_efault +- .word 43b, __retl_efault, 44b, __retl_efault +- .word 45b, __retl_efault, 46b, __retl_efault +- .word 47b, __retl_efault, 48b, __retl_efault +- .word 49b, __retl_efault, 50b, __retl_efault +- .word 51b, __retl_efault, 52b, __retl_efault +- .word 53b, __retl_efault, 54b, __retl_efault +- .word 55b, __retl_efault, 56b, __retl_efault +- .word 57b, __retl_efault, 58b, __retl_efault +- .word 59b, __retl_efault, 60b, __retl_efault +- .word 61b, __retl_efault, 62b, __retl_efault +- .word 63b, __retl_efault, 64b, __retl_efault +- .word 65b, __retl_efault, 66b, __retl_efault +- .previous +diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl +index 6869c7c71ebaf..5c76ebe07e9c2 100644 +--- a/arch/sparc/kernel/syscalls/syscall.tbl ++++ b/arch/sparc/kernel/syscalls/syscall.tbl +@@ -155,7 +155,7 @@ + 123 32 fchown sys_fchown16 + 123 64 fchown sys_fchown + 124 common fchmod sys_fchmod +-125 common recvfrom sys_recvfrom ++125 common recvfrom sys_recvfrom compat_sys_recvfrom + 126 32 setreuid sys_setreuid16 + 126 64 setreuid sys_setreuid + 127 32 setregid sys_setregid16 +@@ -247,7 +247,7 @@ + 204 32 readdir sys_old_readdir compat_sys_old_readdir + 204 64 readdir sys_nis_syscall + 205 common readahead sys_readahead compat_sys_readahead +-206 common socketcall sys_socketcall sys32_socketcall ++206 common socketcall sys_socketcall compat_sys_socketcall + 207 common syslog sys_syslog + 208 common lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie + 209 common fadvise64 sys_fadvise64 compat_sys_fadvise64 +-- +2.43.0 + diff --git a/queue-5.10/sparc-fix-old-compat_sys_select.patch b/queue-5.10/sparc-fix-old-compat_sys_select.patch new file mode 100644 index 00000000000..7e8c9cd04ea --- /dev/null +++ b/queue-5.10/sparc-fix-old-compat_sys_select.patch @@ -0,0 +1,39 @@ +From b7eb7b93586e014f950ead0d0b966cca3deb8a5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Jun 2024 14:07:30 +0200 +Subject: sparc: fix old compat_sys_select() + +From: Arnd Bergmann + +[ Upstream commit bae6428a9fffb2023191b0723e276cf1377a7c9f ] + +sparc has two identical select syscalls at numbers 93 and 230, respectively. +During the conversion to the modern syscall.tbl format, the older one of the +two broke in compat mode, and now refers to the native 64-bit syscall. + +Restore the correct behavior. This has very little effect, as glibc has +been using the newer number anyway. + +Fixes: 6ff645dd683a ("sparc: add system call table generation support") +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/sparc/kernel/syscalls/syscall.tbl | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl +index 78160260991be..6869c7c71ebaf 100644 +--- a/arch/sparc/kernel/syscalls/syscall.tbl ++++ b/arch/sparc/kernel/syscalls/syscall.tbl +@@ -117,7 +117,7 @@ + 90 common dup2 sys_dup2 + 91 32 setfsuid32 sys_setfsuid + 92 common fcntl sys_fcntl compat_sys_fcntl +-93 common select sys_select ++93 common select sys_select compat_sys_select + 94 32 setfsgid32 sys_setfsgid + 95 common fsync sys_fsync + 96 common setpriority sys_setpriority +-- +2.43.0 + diff --git a/queue-5.10/sunrpc-fix-a-null-pointer-deref-in-trace_svc_stats_l.patch b/queue-5.10/sunrpc-fix-a-null-pointer-deref-in-trace_svc_stats_l.patch new file mode 100644 index 00000000000..4f3e024e251 --- /dev/null +++ b/queue-5.10/sunrpc-fix-a-null-pointer-deref-in-trace_svc_stats_l.patch @@ -0,0 +1,102 @@ +From 937d56a86cadf8eec8b3f776a999f21e45e8a169 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Jun 2024 14:27:42 -0400 +Subject: SUNRPC: Fix a NULL pointer deref in trace_svc_stats_latency() + +From: Chuck Lever + +[ Upstream commit 5c11720767f70d34357d00a15ba5a0ad052c40fe ] + +Some paths through svc_process() leave rqst->rq_procinfo set to +NULL, which triggers a crash if tracing happens to be enabled. + +Fixes: 89ff87494c6e ("SUNRPC: Display RPC procedure names instead of proc numbers") +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + include/linux/sunrpc/svc.h | 1 + + include/trace/events/sunrpc.h | 8 ++++---- + net/sunrpc/svc.c | 15 +++++++++++++++ + 3 files changed, 20 insertions(+), 4 deletions(-) + +diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h +index 1cf7a7799cc04..8583825c4aea2 100644 +--- a/include/linux/sunrpc/svc.h ++++ b/include/linux/sunrpc/svc.h +@@ -498,6 +498,7 @@ void svc_wake_up(struct svc_serv *); + void svc_reserve(struct svc_rqst *rqstp, int space); + struct svc_pool * svc_pool_for_cpu(struct svc_serv *serv, int cpu); + char * svc_print_addr(struct svc_rqst *, char *, size_t); ++const char * svc_proc_name(const struct svc_rqst *rqstp); + int svc_encode_result_payload(struct svc_rqst *rqstp, + unsigned int offset, + unsigned int length); +diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h +index 56e4a57d25382..5d34deca0f300 100644 +--- a/include/trace/events/sunrpc.h ++++ b/include/trace/events/sunrpc.h +@@ -1578,7 +1578,7 @@ TRACE_EVENT(svc_process, + __field(u32, vers) + __field(u32, proc) + __string(service, name) +- __string(procedure, rqst->rq_procinfo->pc_name) ++ __string(procedure, svc_proc_name(rqst)) + __string(addr, rqst->rq_xprt ? + rqst->rq_xprt->xpt_remotebuf : "(null)") + ), +@@ -1588,7 +1588,7 @@ TRACE_EVENT(svc_process, + __entry->vers = rqst->rq_vers; + __entry->proc = rqst->rq_proc; + __assign_str(service, name); +- __assign_str(procedure, rqst->rq_procinfo->pc_name); ++ __assign_str(procedure, svc_proc_name(rqst)); + __assign_str(addr, rqst->rq_xprt ? + rqst->rq_xprt->xpt_remotebuf : "(null)"); + ), +@@ -1854,7 +1854,7 @@ TRACE_EVENT(svc_stats_latency, + TP_STRUCT__entry( + __field(u32, xid) + __field(unsigned long, execute) +- __string(procedure, rqst->rq_procinfo->pc_name) ++ __string(procedure, svc_proc_name(rqst)) + __string(addr, rqst->rq_xprt->xpt_remotebuf) + ), + +@@ -1862,7 +1862,7 @@ TRACE_EVENT(svc_stats_latency, + __entry->xid = be32_to_cpu(rqst->rq_xid); + __entry->execute = ktime_to_us(ktime_sub(ktime_get(), + rqst->rq_stime)); +- __assign_str(procedure, rqst->rq_procinfo->pc_name); ++ __assign_str(procedure, svc_proc_name(rqst)); + __assign_str(addr, rqst->rq_xprt->xpt_remotebuf); + ), + +diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c +index ac7b3a93d9920..f8815ae776e68 100644 +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -1612,6 +1612,21 @@ u32 svc_max_payload(const struct svc_rqst *rqstp) + } + EXPORT_SYMBOL_GPL(svc_max_payload); + ++/** ++ * svc_proc_name - Return RPC procedure name in string form ++ * @rqstp: svc_rqst to operate on ++ * ++ * Return value: ++ * Pointer to a NUL-terminated string ++ */ ++const char *svc_proc_name(const struct svc_rqst *rqstp) ++{ ++ if (rqstp && rqstp->rq_procinfo) ++ return rqstp->rq_procinfo->pc_name; ++ return "unknown"; ++} ++ ++ + /** + * svc_encode_result_payload - mark a range of bytes as a result payload + * @rqstp: svc_rqst to operate on +-- +2.43.0 + diff --git a/queue-5.10/sunrpc-fix-null-pointer-dereference-in-svc_rqst_free.patch b/queue-5.10/sunrpc-fix-null-pointer-dereference-in-svc_rqst_free.patch new file mode 100644 index 00000000000..0c165747b8c --- /dev/null +++ b/queue-5.10/sunrpc-fix-null-pointer-dereference-in-svc_rqst_free.patch @@ -0,0 +1,39 @@ +From bca93c53d52ea1a1c7e49aee7ab9904e55d47041 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Jun 2024 14:27:41 -0400 +Subject: SUNRPC: Fix null pointer dereference in svc_rqst_free() + +From: Yunjian Wang + +[ Upstream commit b9f83ffaa0c096b4c832a43964fe6bff3acffe10 ] + +When alloc_pages_node() returns null in svc_rqst_alloc(), the +null rq_scratch_page pointer will be dereferenced when calling +put_page() in svc_rqst_free(). Fix it by adding a null check. + +Addresses-Coverity: ("Dereference after null check") +Fixes: 5191955d6fc6 ("SUNRPC: Prepare for xdr_stream-style decoding on the server-side") +Signed-off-by: Yunjian Wang +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + net/sunrpc/svc.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c +index 26d972c54a593..ac7b3a93d9920 100644 +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -845,7 +845,8 @@ void + svc_rqst_free(struct svc_rqst *rqstp) + { + svc_release_buffer(rqstp); +- put_page(rqstp->rq_scratch_page); ++ if (rqstp->rq_scratch_page) ++ put_page(rqstp->rq_scratch_page); + kfree(rqstp->rq_resp); + kfree(rqstp->rq_argp); + kfree(rqstp->rq_auth_data); +-- +2.43.0 + diff --git a/queue-5.10/sunrpc-fix-svcxdr_init_decode-s-end-of-buffer-calcul.patch b/queue-5.10/sunrpc-fix-svcxdr_init_decode-s-end-of-buffer-calcul.patch new file mode 100644 index 00000000000..28cfe150407 --- /dev/null +++ b/queue-5.10/sunrpc-fix-svcxdr_init_decode-s-end-of-buffer-calcul.patch @@ -0,0 +1,71 @@ +From df79ca92bd3f4e85623b3dfd8ac98e61b9039ce0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Jun 2024 14:27:43 -0400 +Subject: SUNRPC: Fix svcxdr_init_decode's end-of-buffer calculation + +From: Chuck Lever + +[ Upstream commit 90bfc37b5ab91c1a6165e3e5cfc49bf04571b762 ] + +Ensure that stream-based argument decoding can't go past the actual +end of the receive buffer. xdr_init_decode's calculation of the +value of xdr->end over-estimates the end of the buffer because the +Linux kernel RPC server code does not remove the size of the RPC +header from rqstp->rq_arg before calling the upper layer's +dispatcher. + +The server-side still uses the svc_getnl() macros to decode the +RPC call header. These macros reduce the length of the head iov +but do not update the total length of the message in the buffer +(buf->len). + +A proper fix for this would be to replace the use of svc_getnl() and +friends in the RPC header decoder, but that would be a large and +invasive change that would be difficult to backport. + +Fixes: 5191955d6fc6 ("SUNRPC: Prepare for xdr_stream-style decoding on the server-side") +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + include/linux/sunrpc/svc.h | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h +index 8583825c4aea2..f0e09427070cd 100644 +--- a/include/linux/sunrpc/svc.h ++++ b/include/linux/sunrpc/svc.h +@@ -536,16 +536,27 @@ static inline void svc_reserve_auth(struct svc_rqst *rqstp, int space) + } + + /** +- * svcxdr_init_decode - Prepare an xdr_stream for svc Call decoding ++ * svcxdr_init_decode - Prepare an xdr_stream for Call decoding + * @rqstp: controlling server RPC transaction context + * ++ * This function currently assumes the RPC header in rq_arg has ++ * already been decoded. Upon return, xdr->p points to the ++ * location of the upper layer header. + */ + static inline void svcxdr_init_decode(struct svc_rqst *rqstp) + { + struct xdr_stream *xdr = &rqstp->rq_arg_stream; +- struct kvec *argv = rqstp->rq_arg.head; ++ struct xdr_buf *buf = &rqstp->rq_arg; ++ struct kvec *argv = buf->head; + +- xdr_init_decode(xdr, &rqstp->rq_arg, argv->iov_base, NULL); ++ /* ++ * svc_getnl() and friends do not keep the xdr_buf's ::len ++ * field up to date. Refresh that field before initializing ++ * the argument decoding stream. ++ */ ++ buf->len = buf->head->iov_len + buf->page_len + buf->tail->iov_len; ++ ++ xdr_init_decode(xdr, buf, argv->iov_base, NULL); + xdr_set_scratch_page(xdr, rqstp->rq_scratch_page); + } + +-- +2.43.0 + diff --git a/queue-5.10/sunrpc-fix-svcxdr_init_encode-s-buflen-calculation.patch b/queue-5.10/sunrpc-fix-svcxdr_init_encode-s-buflen-calculation.patch new file mode 100644 index 00000000000..0d22e59bde1 --- /dev/null +++ b/queue-5.10/sunrpc-fix-svcxdr_init_encode-s-buflen-calculation.patch @@ -0,0 +1,42 @@ +From 876efd6005a351b63cc47eda6325d59b86a5a8da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Jun 2024 14:27:44 -0400 +Subject: SUNRPC: Fix svcxdr_init_encode's buflen calculation + +From: Chuck Lever + +[ Upstream commit 1242a87da0d8cd2a428e96ca68e7ea899b0f4624 ] + +Commit 2825a7f90753 ("nfsd4: allow encoding across page boundaries") +added an explicit computation of the remaining length in the rq_res +XDR buffer. + +The computation appears to suffer from an "off-by-one" bug. Because +buflen is too large by one page, XDR encoding can run off the end of +the send buffer by eventually trying to use the struct page address +in rq_page_end, which always contains NULL. + +Fixes: bddfdbcddbe2 ("NFSD: Extract the svcxdr_init_encode() helper") +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + include/linux/sunrpc/svc.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h +index f0e09427070cd..00303c636a89d 100644 +--- a/include/linux/sunrpc/svc.h ++++ b/include/linux/sunrpc/svc.h +@@ -579,7 +579,7 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp) + xdr->end = resv->iov_base + PAGE_SIZE - rqstp->rq_auth_slack; + buf->len = resv->iov_len; + xdr->page_ptr = buf->pages - 1; +- buf->buflen = PAGE_SIZE * (1 + rqstp->rq_page_end - buf->pages); ++ buf->buflen = PAGE_SIZE * (rqstp->rq_page_end - buf->pages); + buf->buflen -= rqstp->rq_auth_slack; + xdr->rqst = NULL; + } +-- +2.43.0 + diff --git a/queue-5.10/tracing-net_sched-null-pointer-dereference-in-perf_t.patch b/queue-5.10/tracing-net_sched-null-pointer-dereference-in-perf_t.patch new file mode 100644 index 00000000000..77dd2a27913 --- /dev/null +++ b/queue-5.10/tracing-net_sched-null-pointer-dereference-in-perf_t.patch @@ -0,0 +1,306 @@ +From 54fd514a55ab92b28e457ea6557584719cfb1467 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Jun 2024 02:33:23 +0900 +Subject: tracing/net_sched: NULL pointer dereference in + perf_trace_qdisc_reset() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Yunseong Kim + +[ Upstream commit bab4923132feb3e439ae45962979c5d9d5c7c1f1 ] + +In the TRACE_EVENT(qdisc_reset) NULL dereference occurred from + + qdisc->dev_queue->dev ->name + +This situation simulated from bunch of veths and Bluetooth disconnection +and reconnection. + +During qdisc initialization, qdisc was being set to noop_queue. +In veth_init_queue, the initial tx_num was reduced back to one, +causing the qdisc reset to be called with noop, which led to the kernel +panic. + +I've attached the GitHub gist link that C converted syz-execprogram +source code and 3 log of reproduced vmcore-dmesg. + + https://gist.github.com/yskelg/cc64562873ce249cdd0d5a358b77d740 + +Yeoreum and I use two fuzzing tool simultaneously. + +One process with syz-executor : https://github.com/google/syzkaller + + $ ./syz-execprog -executor=./syz-executor -repeat=1 -sandbox=setuid \ + -enable=none -collide=false log1 + +The other process with perf fuzzer: + https://github.com/deater/perf_event_tests/tree/master/fuzzer + + $ perf_event_tests/fuzzer/perf_fuzzer + +I think this will happen on the kernel version. + + Linux kernel version +v6.7.10, +v6.8, +v6.9 and it could happen in v6.10. + +This occurred from 51270d573a8d. I think this patch is absolutely +necessary. Previously, It was showing not intended string value of name. + +I've reproduced 3 time from my fedora 40 Debug Kernel with any other module +or patched. + + version: 6.10.0-0.rc2.20240608gitdc772f8237f9.29.fc41.aarch64+debug + +[ 5287.164555] veth0_vlan: left promiscuous mode +[ 5287.164929] veth1_macvtap: left promiscuous mode +[ 5287.164950] veth0_macvtap: left promiscuous mode +[ 5287.164983] veth1_vlan: left promiscuous mode +[ 5287.165008] veth0_vlan: left promiscuous mode +[ 5287.165450] veth1_macvtap: left promiscuous mode +[ 5287.165472] veth0_macvtap: left promiscuous mode +[ 5287.165502] veth1_vlan: left promiscuous mode +… +[ 5297.598240] bridge0: port 2(bridge_slave_1) entered blocking state +[ 5297.598262] bridge0: port 2(bridge_slave_1) entered forwarding state +[ 5297.598296] bridge0: port 1(bridge_slave_0) entered blocking state +[ 5297.598313] bridge0: port 1(bridge_slave_0) entered forwarding state +[ 5297.616090] 8021q: adding VLAN 0 to HW filter on device bond0 +[ 5297.620405] bridge0: port 1(bridge_slave_0) entered disabled state +[ 5297.620730] bridge0: port 2(bridge_slave_1) entered disabled state +[ 5297.627247] 8021q: adding VLAN 0 to HW filter on device team0 +[ 5297.629636] bridge0: port 1(bridge_slave_0) entered blocking state +… +[ 5298.002798] bridge_slave_0: left promiscuous mode +[ 5298.002869] bridge0: port 1(bridge_slave_0) entered disabled state +[ 5298.309444] bond0 (unregistering): (slave bond_slave_0): Releasing backup interface +[ 5298.315206] bond0 (unregistering): (slave bond_slave_1): Releasing backup interface +[ 5298.320207] bond0 (unregistering): Released all slaves +[ 5298.354296] hsr_slave_0: left promiscuous mode +[ 5298.360750] hsr_slave_1: left promiscuous mode +[ 5298.374889] veth1_macvtap: left promiscuous mode +[ 5298.374931] veth0_macvtap: left promiscuous mode +[ 5298.374988] veth1_vlan: left promiscuous mode +[ 5298.375024] veth0_vlan: left promiscuous mode +[ 5299.109741] team0 (unregistering): Port device team_slave_1 removed +[ 5299.185870] team0 (unregistering): Port device team_slave_0 removed +… +[ 5300.155443] Bluetooth: hci3: unexpected cc 0x0c03 length: 249 > 1 +[ 5300.155724] Bluetooth: hci3: unexpected cc 0x1003 length: 249 > 9 +[ 5300.155988] Bluetooth: hci3: unexpected cc 0x1001 length: 249 > 9 +…. +[ 5301.075531] team0: Port device team_slave_1 added +[ 5301.085515] bridge0: port 1(bridge_slave_0) entered blocking state +[ 5301.085531] bridge0: port 1(bridge_slave_0) entered disabled state +[ 5301.085588] bridge_slave_0: entered allmulticast mode +[ 5301.085800] bridge_slave_0: entered promiscuous mode +[ 5301.095617] bridge0: port 1(bridge_slave_0) entered blocking state +[ 5301.095633] bridge0: port 1(bridge_slave_0) entered disabled state +… +[ 5301.149734] bond0: (slave bond_slave_0): Enslaving as an active interface with an up link +[ 5301.173234] bond0: (slave bond_slave_0): Enslaving as an active interface with an up link +[ 5301.180517] bond0: (slave bond_slave_1): Enslaving as an active interface with an up link +[ 5301.193481] hsr_slave_0: entered promiscuous mode +[ 5301.204425] hsr_slave_1: entered promiscuous mode +[ 5301.210172] debugfs: Directory 'hsr0' with parent 'hsr' already present! +[ 5301.210185] Cannot create hsr debugfs directory +[ 5301.224061] bond0: (slave bond_slave_1): Enslaving as an active interface with an up link +[ 5301.246901] bond0: (slave bond_slave_0): Enslaving as an active interface with an up link +[ 5301.255934] team0: Port device team_slave_0 added +[ 5301.256480] team0: Port device team_slave_1 added +[ 5301.256948] team0: Port device team_slave_0 added +… +[ 5301.435928] hsr_slave_0: entered promiscuous mode +[ 5301.446029] hsr_slave_1: entered promiscuous mode +[ 5301.455872] debugfs: Directory 'hsr0' with parent 'hsr' already present! +[ 5301.455884] Cannot create hsr debugfs directory +[ 5301.502664] hsr_slave_0: entered promiscuous mode +[ 5301.513675] hsr_slave_1: entered promiscuous mode +[ 5301.526155] debugfs: Directory 'hsr0' with parent 'hsr' already present! +[ 5301.526164] Cannot create hsr debugfs directory +[ 5301.563662] hsr_slave_0: entered promiscuous mode +[ 5301.576129] hsr_slave_1: entered promiscuous mode +[ 5301.580259] debugfs: Directory 'hsr0' with parent 'hsr' already present! +[ 5301.580270] Cannot create hsr debugfs directory +[ 5301.590269] 8021q: adding VLAN 0 to HW filter on device bond0 + +[ 5301.595872] KASAN: null-ptr-deref in range [0x0000000000000130-0x0000000000000137] +[ 5301.595877] Mem abort info: +[ 5301.595881] ESR = 0x0000000096000006 +[ 5301.595885] EC = 0x25: DABT (current EL), IL = 32 bits +[ 5301.595889] SET = 0, FnV = 0 +[ 5301.595893] EA = 0, S1PTW = 0 +[ 5301.595896] FSC = 0x06: level 2 translation fault +[ 5301.595900] Data abort info: +[ 5301.595903] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000 +[ 5301.595907] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 5301.595911] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 5301.595915] [dfff800000000026] address between user and kernel address ranges +[ 5301.595971] Internal error: Oops: 0000000096000006 [#1] SMP +… +[ 5301.596076] CPU: 2 PID: 102769 Comm: +syz-executor.3 Kdump: loaded Tainted: + G W ------- --- 6.10.0-0.rc2.20240608gitdc772f8237f9.29.fc41.aarch64+debug #1 +[ 5301.596080] Hardware name: VMware, Inc. VMware20,1/VBSA, + BIOS VMW201.00V.21805430.BA64.2305221830 05/22/2023 +[ 5301.596082] pstate: 01400005 (nzcv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) +[ 5301.596085] pc : strnlen+0x40/0x88 +[ 5301.596114] lr : trace_event_get_offsets_qdisc_reset+0x6c/0x2b0 +[ 5301.596124] sp : ffff8000beef6b40 +[ 5301.596126] x29: ffff8000beef6b40 x28: dfff800000000000 x27: 0000000000000001 +[ 5301.596131] x26: 6de1800082c62bd0 x25: 1ffff000110aa9e0 x24: ffff800088554f00 +[ 5301.596136] x23: ffff800088554ec0 x22: 0000000000000130 x21: 0000000000000140 +[ 5301.596140] x20: dfff800000000000 x19: ffff8000beef6c60 x18: ffff7000115106d8 +[ 5301.596143] x17: ffff800121bad000 x16: ffff800080020000 x15: 0000000000000006 +[ 5301.596147] x14: 0000000000000002 x13: ffff0001f3ed8d14 x12: ffff700017ddeda5 +[ 5301.596151] x11: 1ffff00017ddeda4 x10: ffff700017ddeda4 x9 : ffff800082cc5eec +[ 5301.596155] x8 : 0000000000000004 x7 : 00000000f1f1f1f1 x6 : 00000000f2f2f200 +[ 5301.596158] x5 : 00000000f3f3f3f3 x4 : ffff700017dded80 x3 : 00000000f204f1f1 +[ 5301.596162] x2 : 0000000000000026 x1 : 0000000000000000 x0 : 0000000000000130 +[ 5301.596166] Call trace: +[ 5301.596175] strnlen+0x40/0x88 +[ 5301.596179] trace_event_get_offsets_qdisc_reset+0x6c/0x2b0 +[ 5301.596182] perf_trace_qdisc_reset+0xb0/0x538 +[ 5301.596184] __traceiter_qdisc_reset+0x68/0xc0 +[ 5301.596188] qdisc_reset+0x43c/0x5e8 +[ 5301.596190] netif_set_real_num_tx_queues+0x288/0x770 +[ 5301.596194] veth_init_queues+0xfc/0x130 [veth] +[ 5301.596198] veth_newlink+0x45c/0x850 [veth] +[ 5301.596202] rtnl_newlink_create+0x2c8/0x798 +[ 5301.596205] __rtnl_newlink+0x92c/0xb60 +[ 5301.596208] rtnl_newlink+0xd8/0x130 +[ 5301.596211] rtnetlink_rcv_msg+0x2e0/0x890 +[ 5301.596214] netlink_rcv_skb+0x1c4/0x380 +[ 5301.596225] rtnetlink_rcv+0x20/0x38 +[ 5301.596227] netlink_unicast+0x3c8/0x640 +[ 5301.596231] netlink_sendmsg+0x658/0xa60 +[ 5301.596234] __sock_sendmsg+0xd0/0x180 +[ 5301.596243] __sys_sendto+0x1c0/0x280 +[ 5301.596246] __arm64_sys_sendto+0xc8/0x150 +[ 5301.596249] invoke_syscall+0xdc/0x268 +[ 5301.596256] el0_svc_common.constprop.0+0x16c/0x240 +[ 5301.596259] do_el0_svc+0x48/0x68 +[ 5301.596261] el0_svc+0x50/0x188 +[ 5301.596265] el0t_64_sync_handler+0x120/0x130 +[ 5301.596268] el0t_64_sync+0x194/0x198 +[ 5301.596272] Code: eb15001f 54000120 d343fc02 12000801 (38f46842) +[ 5301.596285] SMP: stopping secondary CPUs +[ 5301.597053] Starting crashdump kernel... +[ 5301.597057] Bye! + +After applying our patch, I didn't find any kernel panic errors. + +We've found a simple reproducer + + # echo 1 > /sys/kernel/debug/tracing/events/qdisc/qdisc_reset/enable + + # ip link add veth0 type veth peer name veth1 + + Error: Unknown device type. + +However, without our patch applied, I tested upstream 6.10.0-rc3 kernel +using the qdisc_reset event and the ip command on my qemu virtual machine. + +This 2 commands makes always kernel panic. + +Linux version: 6.10.0-rc3 + +[ 0.000000] Linux version 6.10.0-rc3-00164-g44ef20baed8e-dirty +(paran@fedora) (gcc (GCC) 14.1.1 20240522 (Red Hat 14.1.1-4), GNU ld +version 2.41-34.fc40) #20 SMP PREEMPT Sat Jun 15 16:51:25 KST 2024 + +Kernel panic message: + +[ 615.236484] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP +[ 615.237250] Dumping ftrace buffer: +[ 615.237679] (ftrace buffer empty) +[ 615.238097] Modules linked in: veth crct10dif_ce virtio_gpu +virtio_dma_buf drm_shmem_helper drm_kms_helper zynqmp_fpga xilinx_can +xilinx_spi xilinx_selectmap xilinx_core xilinx_pr_decoupler versal_fpga +uvcvideo uvc videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videodev +videobuf2_common mc usbnet deflate zstd ubifs ubi rcar_canfd rcar_can +omap_mailbox ntb_msi_test ntb_hw_epf lattice_sysconfig_spi +lattice_sysconfig ice40_spi gpio_xilinx dwmac_altr_socfpga mdio_regmap +stmmac_platform stmmac pcs_xpcs dfl_fme_region dfl_fme_mgr dfl_fme_br +dfl_afu dfl fpga_region fpga_bridge can can_dev br_netfilter bridge stp +llc atl1c ath11k_pci mhi ath11k_ahb ath11k qmi_helpers ath10k_sdio +ath10k_pci ath10k_core ath mac80211 libarc4 cfg80211 drm fuse backlight ipv6 +Jun 22 02:36:5[3 6k152.62-4sm98k4-0k]v kCePUr:n e1l :P IUDn:a b4le6 +8t oC ohmma: nidpl eN oketr nteali nptaedg i6n.g1 0re.0q-urecs3t- 0at0 +1v6i4r-tgu4a4le fa2d0dbraeeds0se-dir tyd f#f2f08 + 615.252376] Hardware name: linux,dummy-virt (DT) +[ 615.253220] pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS +BTYPE=--) +[ 615.254433] pc : strnlen+0x6c/0xe0 +[ 615.255096] lr : trace_event_get_offsets_qdisc_reset+0x94/0x3d0 +[ 615.256088] sp : ffff800080b269a0 +[ 615.256615] x29: ffff800080b269a0 x28: ffffc070f3f98500 x27: +0000000000000001 +[ 615.257831] x26: 0000000000000010 x25: ffffc070f3f98540 x24: +ffffc070f619cf60 +[ 615.259020] x23: 0000000000000128 x22: 0000000000000138 x21: +dfff800000000000 +[ 615.260241] x20: ffffc070f631ad00 x19: 0000000000000128 x18: +ffffc070f448b800 +[ 615.261454] x17: 0000000000000000 x16: 0000000000000001 x15: +ffffc070f4ba2a90 +[ 615.262635] x14: ffff700010164d73 x13: 1ffff80e1e8d5eb3 x12: +1ffff00010164d72 +[ 615.263877] x11: ffff700010164d72 x10: dfff800000000000 x9 : +ffffc070e85d6184 +[ 615.265047] x8 : ffffc070e4402070 x7 : 000000000000f1f1 x6 : +000000001504a6d3 +[ 615.266336] x5 : ffff28ca21122140 x4 : ffffc070f5043ea8 x3 : +0000000000000000 +[ 615.267528] x2 : 0000000000000025 x1 : 0000000000000000 x0 : +0000000000000000 +[ 615.268747] Call trace: +[ 615.269180] strnlen+0x6c/0xe0 +[ 615.269767] trace_event_get_offsets_qdisc_reset+0x94/0x3d0 +[ 615.270716] trace_event_raw_event_qdisc_reset+0xe8/0x4e8 +[ 615.271667] __traceiter_qdisc_reset+0xa0/0x140 +[ 615.272499] qdisc_reset+0x554/0x848 +[ 615.273134] netif_set_real_num_tx_queues+0x360/0x9a8 +[ 615.274050] veth_init_queues+0x110/0x220 [veth] +[ 615.275110] veth_newlink+0x538/0xa50 [veth] +[ 615.276172] __rtnl_newlink+0x11e4/0x1bc8 +[ 615.276944] rtnl_newlink+0xac/0x120 +[ 615.277657] rtnetlink_rcv_msg+0x4e4/0x1370 +[ 615.278409] netlink_rcv_skb+0x25c/0x4f0 +[ 615.279122] rtnetlink_rcv+0x48/0x70 +[ 615.279769] netlink_unicast+0x5a8/0x7b8 +[ 615.280462] netlink_sendmsg+0xa70/0x1190 + +Yeoreum and I don't know if the patch we wrote will fix the underlying +cause, but we think that priority is to prevent kernel panic happening. +So, we're sending this patch. + +Fixes: 51270d573a8d ("tracing/net_sched: Fix tracepoints that save qdisc_dev() as a string") +Link: https://lore.kernel.org/lkml/20240229143432.273b4871@gandalf.local.home/t/ +Cc: netdev@vger.kernel.org +Tested-by: Yunseong Kim +Signed-off-by: Yunseong Kim +Signed-off-by: Yeoreum Yun +Link: https://lore.kernel.org/r/20240624173320.24945-4-yskelg@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + include/trace/events/qdisc.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/trace/events/qdisc.h b/include/trace/events/qdisc.h +index a50df41634c58..f661d3d7c410a 100644 +--- a/include/trace/events/qdisc.h ++++ b/include/trace/events/qdisc.h +@@ -53,7 +53,7 @@ TRACE_EVENT(qdisc_reset, + TP_ARGS(q), + + TP_STRUCT__entry( +- __string( dev, qdisc_dev(q)->name ) ++ __string( dev, qdisc_dev(q) ? qdisc_dev(q)->name : "(null)" ) + __string( kind, q->ops->id ) + __field( u32, parent ) + __field( u32, handle ) +-- +2.43.0 + diff --git a/queue-5.10/xdp-allow-registering-memory-model-without-rxq-refer.patch b/queue-5.10/xdp-allow-registering-memory-model-without-rxq-refer.patch new file mode 100644 index 00000000000..75b6d7367ed --- /dev/null +++ b/queue-5.10/xdp-allow-registering-memory-model-without-rxq-refer.patch @@ -0,0 +1,214 @@ +From c0534d6780d46511be13f25f357f026ab038e5c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Jan 2022 16:08:06 +0100 +Subject: xdp: Allow registering memory model without rxq reference +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Toke Høiland-Jørgensen + +[ Upstream commit 4a48ef70b93b8c7ed5190adfca18849e76387b80 ] + +The functions that register an XDP memory model take a struct xdp_rxq as +parameter, but the RXQ is not actually used for anything other than pulling +out the struct xdp_mem_info that it embeds. So refactor the register +functions and export variants that just take a pointer to the xdp_mem_info. + +This is in preparation for enabling XDP_REDIRECT in bpf_prog_run(), using a +page_pool instance that is not connected to any network device. + +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: Alexei Starovoitov +Link: https://lore.kernel.org/bpf/20220103150812.87914-2-toke@redhat.com +Stable-dep-of: 7e9f79428372 ("xdp: Remove WARN() from __xdp_reg_mem_model()") +Signed-off-by: Sasha Levin +--- + include/net/xdp.h | 3 ++ + net/core/xdp.c | 92 +++++++++++++++++++++++++++++++---------------- + 2 files changed, 65 insertions(+), 30 deletions(-) + +diff --git a/include/net/xdp.h b/include/net/xdp.h +index 9dab2bc6f187b..9e6c10b323b8e 100644 +--- a/include/net/xdp.h ++++ b/include/net/xdp.h +@@ -218,6 +218,9 @@ bool xdp_rxq_info_is_reg(struct xdp_rxq_info *xdp_rxq); + int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq, + enum xdp_mem_type type, void *allocator); + void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq); ++int xdp_reg_mem_model(struct xdp_mem_info *mem, ++ enum xdp_mem_type type, void *allocator); ++void xdp_unreg_mem_model(struct xdp_mem_info *mem); + + /* Drivers not supporting XDP metadata can use this helper, which + * rejects any room expansion for metadata as a result. +diff --git a/net/core/xdp.c b/net/core/xdp.c +index 0f0b65981614b..6e6b89d5f77ed 100644 +--- a/net/core/xdp.c ++++ b/net/core/xdp.c +@@ -110,20 +110,15 @@ static void mem_allocator_disconnect(void *allocator) + mutex_unlock(&mem_id_lock); + } + +-void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq) ++void xdp_unreg_mem_model(struct xdp_mem_info *mem) + { + struct xdp_mem_allocator *xa; +- int type = xdp_rxq->mem.type; +- int id = xdp_rxq->mem.id; ++ int type = mem->type; ++ int id = mem->id; + + /* Reset mem info to defaults */ +- xdp_rxq->mem.id = 0; +- xdp_rxq->mem.type = 0; +- +- if (xdp_rxq->reg_state != REG_STATE_REGISTERED) { +- WARN(1, "Missing register, driver bug"); +- return; +- } ++ mem->id = 0; ++ mem->type = 0; + + if (id == 0) + return; +@@ -135,6 +130,17 @@ void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq) + rcu_read_unlock(); + } + } ++EXPORT_SYMBOL_GPL(xdp_unreg_mem_model); ++ ++void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq) ++{ ++ if (xdp_rxq->reg_state != REG_STATE_REGISTERED) { ++ WARN(1, "Missing register, driver bug"); ++ return; ++ } ++ ++ xdp_unreg_mem_model(&xdp_rxq->mem); ++} + EXPORT_SYMBOL_GPL(xdp_rxq_info_unreg_mem_model); + + void xdp_rxq_info_unreg(struct xdp_rxq_info *xdp_rxq) +@@ -260,28 +266,24 @@ static bool __is_supported_mem_type(enum xdp_mem_type type) + return true; + } + +-int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq, +- enum xdp_mem_type type, void *allocator) ++static struct xdp_mem_allocator *__xdp_reg_mem_model(struct xdp_mem_info *mem, ++ enum xdp_mem_type type, ++ void *allocator) + { + struct xdp_mem_allocator *xdp_alloc; + gfp_t gfp = GFP_KERNEL; + int id, errno, ret; + void *ptr; + +- if (xdp_rxq->reg_state != REG_STATE_REGISTERED) { +- WARN(1, "Missing register, driver bug"); +- return -EFAULT; +- } +- + if (!__is_supported_mem_type(type)) +- return -EOPNOTSUPP; ++ return ERR_PTR(-EOPNOTSUPP); + +- xdp_rxq->mem.type = type; ++ mem->type = type; + + if (!allocator) { + if (type == MEM_TYPE_PAGE_POOL) +- return -EINVAL; /* Setup time check page_pool req */ +- return 0; ++ return ERR_PTR(-EINVAL); /* Setup time check page_pool req */ ++ return NULL; + } + + /* Delay init of rhashtable to save memory if feature isn't used */ +@@ -291,13 +293,13 @@ int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq, + mutex_unlock(&mem_id_lock); + if (ret < 0) { + WARN_ON(1); +- return ret; ++ return ERR_PTR(ret); + } + } + + xdp_alloc = kzalloc(sizeof(*xdp_alloc), gfp); + if (!xdp_alloc) +- return -ENOMEM; ++ return ERR_PTR(-ENOMEM); + + mutex_lock(&mem_id_lock); + id = __mem_id_cyclic_get(gfp); +@@ -305,15 +307,15 @@ int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq, + errno = id; + goto err; + } +- xdp_rxq->mem.id = id; +- xdp_alloc->mem = xdp_rxq->mem; ++ mem->id = id; ++ xdp_alloc->mem = *mem; + xdp_alloc->allocator = allocator; + + /* Insert allocator into ID lookup table */ + ptr = rhashtable_insert_slow(mem_id_ht, &id, &xdp_alloc->node); + if (IS_ERR(ptr)) { +- ida_simple_remove(&mem_id_pool, xdp_rxq->mem.id); +- xdp_rxq->mem.id = 0; ++ ida_simple_remove(&mem_id_pool, mem->id); ++ mem->id = 0; + errno = PTR_ERR(ptr); + goto err; + } +@@ -323,13 +325,43 @@ int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq, + + mutex_unlock(&mem_id_lock); + +- trace_mem_connect(xdp_alloc, xdp_rxq); +- return 0; ++ return xdp_alloc; + err: + mutex_unlock(&mem_id_lock); + kfree(xdp_alloc); +- return errno; ++ return ERR_PTR(errno); ++} ++ ++int xdp_reg_mem_model(struct xdp_mem_info *mem, ++ enum xdp_mem_type type, void *allocator) ++{ ++ struct xdp_mem_allocator *xdp_alloc; ++ ++ xdp_alloc = __xdp_reg_mem_model(mem, type, allocator); ++ if (IS_ERR(xdp_alloc)) ++ return PTR_ERR(xdp_alloc); ++ return 0; ++} ++EXPORT_SYMBOL_GPL(xdp_reg_mem_model); ++ ++int xdp_rxq_info_reg_mem_model(struct xdp_rxq_info *xdp_rxq, ++ enum xdp_mem_type type, void *allocator) ++{ ++ struct xdp_mem_allocator *xdp_alloc; ++ ++ if (xdp_rxq->reg_state != REG_STATE_REGISTERED) { ++ WARN(1, "Missing register, driver bug"); ++ return -EFAULT; ++ } ++ ++ xdp_alloc = __xdp_reg_mem_model(&xdp_rxq->mem, type, allocator); ++ if (IS_ERR(xdp_alloc)) ++ return PTR_ERR(xdp_alloc); ++ ++ trace_mem_connect(xdp_alloc, xdp_rxq); ++ return 0; + } ++ + EXPORT_SYMBOL_GPL(xdp_rxq_info_reg_mem_model); + + /* XDP RX runs under NAPI protection, and in different delivery error +-- +2.43.0 + diff --git a/queue-5.10/xdp-move-the-rxq_info.mem-clearing-to-unreg_mem_mode.patch b/queue-5.10/xdp-move-the-rxq_info.mem-clearing-to-unreg_mem_mode.patch new file mode 100644 index 00000000000..5ff244eb030 --- /dev/null +++ b/queue-5.10/xdp-move-the-rxq_info.mem-clearing-to-unreg_mem_mode.patch @@ -0,0 +1,70 @@ +From 800d5efeaa4819009642d2fec8c039672e68cde7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Jun 2021 15:16:12 -0700 +Subject: xdp: Move the rxq_info.mem clearing to unreg_mem_model() + +From: Jakub Kicinski + +[ Upstream commit a78cae2476812cecaa4a33d0086bbb53986906bc ] + +xdp_rxq_info_unreg() implicitly calls xdp_rxq_info_unreg_mem_model(). +This may well be confusing to the driver authors, and lead to double free +if they call xdp_rxq_info_unreg_mem_model() before xdp_rxq_info_unreg() +(when mem model type == MEM_TYPE_PAGE_POOL). + +In fact error path of mvpp2_rxq_init() seems to currently do exactly that. + +The double free will result in refcount underflow in page_pool_destroy(). +Make the interface a little more programmer friendly by clearing type and +id so that xdp_rxq_info_unreg_mem_model() can be called multiple times. + +Signed-off-by: Jakub Kicinski +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20210625221612.2637086-1-kuba@kernel.org +Stable-dep-of: 7e9f79428372 ("xdp: Remove WARN() from __xdp_reg_mem_model()") +Signed-off-by: Sasha Levin +--- + net/core/xdp.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/net/core/xdp.c b/net/core/xdp.c +index b8d7fa47d293c..0f0b65981614b 100644 +--- a/net/core/xdp.c ++++ b/net/core/xdp.c +@@ -113,8 +113,13 @@ static void mem_allocator_disconnect(void *allocator) + void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq) + { + struct xdp_mem_allocator *xa; ++ int type = xdp_rxq->mem.type; + int id = xdp_rxq->mem.id; + ++ /* Reset mem info to defaults */ ++ xdp_rxq->mem.id = 0; ++ xdp_rxq->mem.type = 0; ++ + if (xdp_rxq->reg_state != REG_STATE_REGISTERED) { + WARN(1, "Missing register, driver bug"); + return; +@@ -123,7 +128,7 @@ void xdp_rxq_info_unreg_mem_model(struct xdp_rxq_info *xdp_rxq) + if (id == 0) + return; + +- if (xdp_rxq->mem.type == MEM_TYPE_PAGE_POOL) { ++ if (type == MEM_TYPE_PAGE_POOL) { + rcu_read_lock(); + xa = rhashtable_lookup(mem_id_ht, &id, mem_id_rht_params); + page_pool_destroy(xa->page_pool); +@@ -144,10 +149,6 @@ void xdp_rxq_info_unreg(struct xdp_rxq_info *xdp_rxq) + + xdp_rxq->reg_state = REG_STATE_UNREGISTERED; + xdp_rxq->dev = NULL; +- +- /* Reset mem info to defaults */ +- xdp_rxq->mem.id = 0; +- xdp_rxq->mem.type = 0; + } + EXPORT_SYMBOL_GPL(xdp_rxq_info_unreg); + +-- +2.43.0 + diff --git a/queue-5.10/xdp-remove-warn-from-__xdp_reg_mem_model.patch b/queue-5.10/xdp-remove-warn-from-__xdp_reg_mem_model.patch new file mode 100644 index 00000000000..5200035dd5a --- /dev/null +++ b/queue-5.10/xdp-remove-warn-from-__xdp_reg_mem_model.patch @@ -0,0 +1,76 @@ +From 47554d041ba9cd87443036f2b53cfd22e700c077 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Jun 2024 11:07:47 +0300 +Subject: xdp: Remove WARN() from __xdp_reg_mem_model() + +From: Daniil Dulov + +[ Upstream commit 7e9f79428372c6eab92271390851be34ab26bfb4 ] + +syzkaller reports a warning in __xdp_reg_mem_model(). + +The warning occurs only if __mem_id_init_hash_table() returns an error. It +returns the error in two cases: + + 1. memory allocation fails; + 2. rhashtable_init() fails when some fields of rhashtable_params + struct are not initialized properly. + +The second case cannot happen since there is a static const rhashtable_params +struct with valid fields. So, warning is only triggered when there is a +problem with memory allocation. + +Thus, there is no sense in using WARN() to handle this error and it can be +safely removed. + +WARNING: CPU: 0 PID: 5065 at net/core/xdp.c:299 __xdp_reg_mem_model+0x2d9/0x650 net/core/xdp.c:299 + +CPU: 0 PID: 5065 Comm: syz-executor883 Not tainted 6.8.0-syzkaller-05271-gf99c5f563c17 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024 +RIP: 0010:__xdp_reg_mem_model+0x2d9/0x650 net/core/xdp.c:299 + +Call Trace: + xdp_reg_mem_model+0x22/0x40 net/core/xdp.c:344 + xdp_test_run_setup net/bpf/test_run.c:188 [inline] + bpf_test_run_xdp_live+0x365/0x1e90 net/bpf/test_run.c:377 + bpf_prog_test_run_xdp+0x813/0x11b0 net/bpf/test_run.c:1267 + bpf_prog_test_run+0x33a/0x3b0 kernel/bpf/syscall.c:4240 + __sys_bpf+0x48d/0x810 kernel/bpf/syscall.c:5649 + __do_sys_bpf kernel/bpf/syscall.c:5738 [inline] + __se_sys_bpf kernel/bpf/syscall.c:5736 [inline] + __x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:5736 + do_syscall_64+0xfb/0x240 + entry_SYSCALL_64_after_hwframe+0x6d/0x75 + +Found by Linux Verification Center (linuxtesting.org) with syzkaller. + +Fixes: 8d5d88527587 ("xdp: rhashtable with allocator ID to pointer mapping") +Signed-off-by: Daniil Dulov +Signed-off-by: Daniel Borkmann +Acked-by: Jesper Dangaard Brouer +Link: https://lore.kernel.org/all/20240617162708.492159-1-d.dulov@aladdin.ru +Link: https://lore.kernel.org/bpf/20240624080747.36858-1-d.dulov@aladdin.ru +Signed-off-by: Sasha Levin +--- + net/core/xdp.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/net/core/xdp.c b/net/core/xdp.c +index 6e6b89d5f77ed..eb5045924efaa 100644 +--- a/net/core/xdp.c ++++ b/net/core/xdp.c +@@ -291,10 +291,8 @@ static struct xdp_mem_allocator *__xdp_reg_mem_model(struct xdp_mem_info *mem, + mutex_lock(&mem_id_lock); + ret = __mem_id_init_hash_table(); + mutex_unlock(&mem_id_lock); +- if (ret < 0) { +- WARN_ON(1); ++ if (ret < 0) + return ERR_PTR(ret); +- } + } + + xdp_alloc = kzalloc(sizeof(*xdp_alloc), gfp); +-- +2.43.0 +