From: Greg Kroah-Hartman Date: Thu, 25 Jun 2026 10:21:08 +0000 (+0100) Subject: 7.0-stable patches X-Git-Tag: v6.18.37~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=796dc1877d8c413da6269e6fc6811de44fed5f96;p=thirdparty%2Fkernel%2Fstable-queue.git 7.0-stable patches added patches: agp-amd64-fix-broken-error-propagation-in-agp_amd64_probe.patch bpf-fix-null-pointer-dereference-in-bpf_sk_storage_clone-and-diag-paths.patch i2c-stub-reject-i2c-block-transfers-with-invalid-length.patch net-qualcomm-rmnet-fix-endpoint-use-after-free-in-rmnet_dellink.patch --- diff --git a/queue-7.0/agp-amd64-fix-broken-error-propagation-in-agp_amd64_probe.patch b/queue-7.0/agp-amd64-fix-broken-error-propagation-in-agp_amd64_probe.patch new file mode 100644 index 0000000000..acbd322172 --- /dev/null +++ b/queue-7.0/agp-amd64-fix-broken-error-propagation-in-agp_amd64_probe.patch @@ -0,0 +1,52 @@ +From b08472db93b1ccff84a7adec5779d47f0e9d3a30 Mon Sep 17 00:00:00 2001 +From: Mingyu Wang <25181214217@stu.xidian.edu.cn> +Date: Mon, 4 May 2026 15:48:23 +0800 +Subject: agp/amd64: Fix broken error propagation in agp_amd64_probe() + +From: Mingyu Wang <25181214217@stu.xidian.edu.cn> + +commit b08472db93b1ccff84a7adec5779d47f0e9d3a30 upstream. + +A NULL pointer dereference was observed in the AMD64 AGP driver when +running in a virtualized environment (e.g. qemu/kvm) without a physical +AMD northbridge. The crash occurs in amd64_fetch_size() when attempting +to dereference the pointer returned by node_to_amd_nb(0). + +The root cause of this crash is broken error propagation in +agp_amd64_probe(): When no AMD northbridges are found, cache_nbs() +correctly returns -ENODEV. However, the probe function erroneously +checks the return value against exactly -1, rather than < 0. + +As a result, the hardware absence error is masked, allowing the driver +to improperly proceed with initialization. It eventually calls +agp_add_bridge(), which invokes amd64_fetch_size(). Since the hardware +does not exist, node_to_amd_nb(0) returns NULL, leading to a General +Protection Fault (GPF) when accessing its ->misc member. + +Fix the issue by correcting the error check in agp_amd64_probe() to +abort properly when cache_nbs() returns any negative error code. This +prevents the driver from erroneously proceeding without hardware, thereby +avoiding the subsequent NULL pointer dereference at its source. + +Fixes: a32073bffc65 ("[PATCH] x86_64: Clean and enhance up K8 northbridge access code") +Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn> +Signed-off-by: Lukas Wunner +Reviewed-by: Lukas Wunner +Cc: stable@vger.kernel.org # v2.6.18+ +Link: https://patch.msgid.link/20260504074823.99377-1-w15303746062@163.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/agp/amd64-agp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/char/agp/amd64-agp.c ++++ b/drivers/char/agp/amd64-agp.c +@@ -546,7 +546,7 @@ static int agp_amd64_probe(struct pci_de + /* Fill in the mode register */ + pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode); + +- if (cache_nbs(pdev, cap_ptr) == -1) { ++ if (cache_nbs(pdev, cap_ptr) < 0) { + agp_put_bridge(bridge); + return -ENODEV; + } diff --git a/queue-7.0/bpf-fix-null-pointer-dereference-in-bpf_sk_storage_clone-and-diag-paths.patch b/queue-7.0/bpf-fix-null-pointer-dereference-in-bpf_sk_storage_clone-and-diag-paths.patch new file mode 100644 index 0000000000..c1cd4bbc72 --- /dev/null +++ b/queue-7.0/bpf-fix-null-pointer-dereference-in-bpf_sk_storage_clone-and-diag-paths.patch @@ -0,0 +1,100 @@ +From 375e4e33c18dfa05c5dfd5f3dfffeb29343dd4c7 Mon Sep 17 00:00:00 2001 +From: Weiming Shi +Date: Tue, 21 Apr 2026 23:54:12 -0700 +Subject: bpf: Fix NULL pointer dereference in bpf_sk_storage_clone and diag paths + +From: Weiming Shi + +commit 375e4e33c18dfa05c5dfd5f3dfffeb29343dd4c7 upstream. + +bpf_selem_unlink_nofail() sets SDATA(selem)->smap to NULL before +removing the selem from the storage hlist. A concurrent RCU reader in +bpf_sk_storage_clone() can observe the selem still on the list with +smap already NULL, causing a NULL pointer dereference. + + general protection fault, probably for non-canonical address 0xdffffc000000000a: + KASAN: null-ptr-deref in range [0x0000000000000050-0x0000000000000057] + RIP: 0010:bpf_sk_storage_clone+0x1cd/0xaa0 net/core/bpf_sk_storage.c:174 + Call Trace: + + sk_clone+0xfed/0x1980 net/core/sock.c:2591 + inet_csk_clone_lock+0x30/0x760 net/ipv4/inet_connection_sock.c:1222 + tcp_create_openreq_child+0x35/0x2680 net/ipv4/tcp_minisocks.c:571 + tcp_v4_syn_recv_sock+0x123/0xf90 net/ipv4/tcp_ipv4.c:1729 + tcp_check_req+0x8e1/0x2580 include/net/tcp.h:855 + tcp_v4_rcv+0x1845/0x3b80 net/ipv4/tcp_ipv4.c:2347 + +Add a NULL check for smap in bpf_sk_storage_clone(). + +bpf_sk_storage_diag_put_all() has the same issue. Add a NULL check +and pass the validated smap directly to diag_get(), which is refactored +to take smap as a parameter instead of reading it internally. + +bpf_sk_storage_diag_put() uses diag->maps[i] which is always valid +under its refcount, so diag->maps[i] is passed directly to diag_get(). + +Fixes: 5d800f87d0a5 ("bpf: Support lockless unlink when freeing map or local storage") +Reported-by: Xiang Mei +Acked-by: Amery Hung +Signed-off-by: Weiming Shi +Signed-off-by: Martin KaFai Lau +Link: https://patch.msgid.link/20260422065411.1007737-2-bestswngs@gmail.com +Signed-off-by: Greg Kroah-Hartman +--- + net/core/bpf_sk_storage.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +--- a/net/core/bpf_sk_storage.c ++++ b/net/core/bpf_sk_storage.c +@@ -172,7 +172,7 @@ int bpf_sk_storage_clone(const struct so + struct bpf_map *map; + + smap = rcu_dereference(SDATA(selem)->smap); +- if (!(smap->map.map_flags & BPF_F_CLONE)) ++ if (!smap || !(smap->map.map_flags & BPF_F_CLONE)) + continue; + + /* Note that for lockless listeners adding new element +@@ -534,10 +534,10 @@ err_free: + } + EXPORT_SYMBOL_GPL(bpf_sk_storage_diag_alloc); + +-static int diag_get(struct bpf_local_storage_data *sdata, struct sk_buff *skb) ++static int diag_get(struct bpf_local_storage_map *smap, ++ struct bpf_local_storage_data *sdata, struct sk_buff *skb) + { + struct nlattr *nla_stg, *nla_value; +- struct bpf_local_storage_map *smap; + + /* It cannot exceed max nlattr's payload */ + BUILD_BUG_ON(U16_MAX - NLA_HDRLEN < BPF_LOCAL_STORAGE_MAX_VALUE_SIZE); +@@ -546,7 +546,6 @@ static int diag_get(struct bpf_local_sto + if (!nla_stg) + return -EMSGSIZE; + +- smap = rcu_dereference(sdata->smap); + if (nla_put_u32(skb, SK_DIAG_BPF_STORAGE_MAP_ID, smap->map.id)) + goto errout; + +@@ -599,9 +598,11 @@ static int bpf_sk_storage_diag_put_all(s + saved_len = skb->len; + hlist_for_each_entry_rcu(selem, &sk_storage->list, snode) { + smap = rcu_dereference(SDATA(selem)->smap); ++ if (!smap) ++ continue; + diag_size += nla_value_size(smap->map.value_size); + +- if (nla_stgs && diag_get(SDATA(selem), skb)) ++ if (nla_stgs && diag_get(smap, SDATA(selem), skb)) + /* Continue to learn diag_size */ + err = -EMSGSIZE; + } +@@ -668,7 +669,7 @@ int bpf_sk_storage_diag_put(struct bpf_s + + diag_size += nla_value_size(diag->maps[i]->value_size); + +- if (nla_stgs && diag_get(sdata, skb)) ++ if (nla_stgs && diag_get((struct bpf_local_storage_map *)diag->maps[i], sdata, skb)) + /* Continue to learn diag_size */ + err = -EMSGSIZE; + } diff --git a/queue-7.0/i2c-stub-reject-i2c-block-transfers-with-invalid-length.patch b/queue-7.0/i2c-stub-reject-i2c-block-transfers-with-invalid-length.patch new file mode 100644 index 0000000000..a602798c41 --- /dev/null +++ b/queue-7.0/i2c-stub-reject-i2c-block-transfers-with-invalid-length.patch @@ -0,0 +1,71 @@ +From 6036b5067a8199ba7a2dc7b377d4b9dd276d5f9e Mon Sep 17 00:00:00 2001 +From: Weiming Shi +Date: Wed, 15 Apr 2026 01:23:39 +0800 +Subject: i2c: stub: Reject I2C block transfers with invalid length + +From: Weiming Shi + +commit 6036b5067a8199ba7a2dc7b377d4b9dd276d5f9e upstream. + +The I2C_SMBUS_I2C_BLOCK_DATA case in stub_xfer() uses data->block[0] +as the transfer length. The existing check only clamps it to avoid +overrunning the chip->words[256] register array, but does not validate +it against I2C_SMBUS_BLOCK_MAX (32), which is the limit of the union +i2c_smbus_data.block buffer (34 bytes total). The driver is a +development/test tool (CONFIG_I2C_STUB=m, not built by default) +that must be loaded with a chip_addr= parameter. + +A local user with access to /dev/i2c-* can issue an I2C_SMBUS ioctl +with I2C_SMBUS_I2C_BLOCK_DATA and data->block[0] > 32, causing +stub_xfer() to read or write past the end of the union +i2c_smbus_data.block buffer: + + BUG: KASAN: stack-out-of-bounds in stub_xfer (drivers/i2c/i2c-stub.c:223) + Read of size 1 at addr ffff88800abcfd92 by task exploit/81 + Call Trace: + + stub_xfer (drivers/i2c/i2c-stub.c:223) + __i2c_smbus_xfer (drivers/i2c/i2c-core-smbus.c:593) + i2c_smbus_xfer (drivers/i2c/i2c-core-smbus.c:536) + i2cdev_ioctl_smbus (drivers/i2c/i2c-dev.c:391) + i2cdev_ioctl (drivers/i2c/i2c-dev.c:478) + __x64_sys_ioctl (fs/ioctl.c:583) + do_syscall_64 (arch/x86/entry/syscall_64.c:94) + entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) + + +The bug exists because i2c-stub implements .smbus_xfer directly, +bypassing the I2C_SMBUS_BLOCK_MAX validation in +i2c_smbus_xfer_emulated(). The I2C_SMBUS_BLOCK_DATA case in the same +function correctly validates against I2C_SMBUS_BLOCK_MAX, but the +I2C_SMBUS_I2C_BLOCK_DATA case does not. + +Fix by rejecting transfers with data->block[0] == 0 or +data->block[0] > I2C_SMBUS_BLOCK_MAX with -EINVAL, consistent with +both the I2C_SMBUS_BLOCK_DATA case in the same function and the +I2C_SMBUS_I2C_BLOCK_DATA validation in i2c_smbus_xfer_emulated(). + +Fixes: 4710317891e4 ("i2c-stub: Implement I2C block support") +Reported-by: Xiang Mei +Signed-off-by: Weiming Shi +Reviewed-by: Jean Delvare +Signed-off-by: Wolfram Sang +Signed-off-by: Greg Kroah-Hartman +--- + drivers/i2c/i2c-stub.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/i2c/i2c-stub.c ++++ b/drivers/i2c/i2c-stub.c +@@ -214,6 +214,11 @@ static s32 stub_xfer(struct i2c_adapter + * We ignore banks here, because banked chips don't use I2C + * block transfers + */ ++ if (data->block[0] == 0 || ++ data->block[0] > I2C_SMBUS_BLOCK_MAX) { ++ ret = -EINVAL; ++ break; ++ } + if (data->block[0] > 256 - command) /* Avoid overrun */ + data->block[0] = 256 - command; + len = data->block[0]; diff --git a/queue-7.0/net-qualcomm-rmnet-fix-endpoint-use-after-free-in-rmnet_dellink.patch b/queue-7.0/net-qualcomm-rmnet-fix-endpoint-use-after-free-in-rmnet_dellink.patch new file mode 100644 index 0000000000..f3f3b27f16 --- /dev/null +++ b/queue-7.0/net-qualcomm-rmnet-fix-endpoint-use-after-free-in-rmnet_dellink.patch @@ -0,0 +1,87 @@ +From d00c953a8f69921f484b629801766da68f27f658 Mon Sep 17 00:00:00 2001 +From: Weiming Shi +Date: Thu, 14 May 2026 05:25:12 -0700 +Subject: net: qualcomm: rmnet: fix endpoint use-after-free in rmnet_dellink() + +From: Weiming Shi + +commit d00c953a8f69921f484b629801766da68f27f658 upstream. + +rmnet_dellink() removes the endpoint from the hash table with +hlist_del_init_rcu() and then immediately frees it with kfree(). However, +RCU readers on the receive path (rmnet_rx_handler -> +__rmnet_map_ingress_handler) may still hold a reference to the endpoint and +dereference ep->egress_dev after the memory has been freed. The endpoint is +a kmalloc-32 object, and the stale read at offset 8 corresponds to the +egress_dev pointer. + + BUG: unable to handle page fault for address: ffffffffde942eef + Oops: 0002 [#1] SMP NOPTI + CPU: 1 UID: 0 PID: 137 Comm: poc_write Not tainted 7.0.0+ #4 PREEMPTLAZY + RIP: 0010:rmnet_vnd_rx_fixup (rmnet_vnd.c:27) + Call Trace: + + __rmnet_map_ingress_handler (rmnet_handlers.c:48 rmnet_handlers.c:101) + rmnet_rx_handler (rmnet_handlers.c:129 rmnet_handlers.c:235) + __netif_receive_skb_core.constprop.0 (net/core/dev.c:6096) + __netif_receive_skb_one_core (net/core/dev.c:6208) + netif_receive_skb (net/core/dev.c:6467) + tun_get_user (drivers/net/tun.c:1955) + tun_chr_write_iter (drivers/net/tun.c:2003) + vfs_write (fs/read_write.c:688) + ksys_write (fs/read_write.c:740) + + +Add an rcu_head field to struct rmnet_endpoint and replace kfree() with +kfree_rcu() so the endpoint memory remains valid through the RCU grace +period. Also remove the rmnet_vnd_dellink() call and inline only the +nr_rmnet_devs decrement, since rmnet_vnd_dellink() would set +ep->egress_dev to NULL during the grace period, creating a data race +with lockless readers. + +Fixes: ceed73a2cf4a ("drivers: net: ethernet: qualcomm: rmnet: Initial implementation") +Reported-by: Xiang Mei +Signed-off-by: Weiming Shi +Link: https://patch.msgid.link/20260514122511.3083479-2-bestswngs@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c | 8 ++++---- + drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h | 1 + + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.c +@@ -213,8 +213,8 @@ static void rmnet_dellink(struct net_dev + ep = rmnet_get_endpoint(real_port, mux_id); + if (ep) { + hlist_del_init_rcu(&ep->hlnode); +- rmnet_vnd_dellink(mux_id, real_port, ep); +- kfree(ep); ++ real_port->nr_rmnet_devs--; ++ kfree_rcu(ep, rcu); + } + + netdev_upper_dev_unlink(real_dev, dev); +@@ -238,9 +238,9 @@ static void rmnet_force_unassociate_devi + hash_for_each_safe(port->muxed_ep, bkt_ep, tmp_ep, ep, hlnode) { + unregister_netdevice_queue(ep->egress_dev, &list); + netdev_upper_dev_unlink(real_dev, ep->egress_dev); +- rmnet_vnd_dellink(ep->mux_id, port, ep); + hlist_del_init_rcu(&ep->hlnode); +- kfree(ep); ++ port->nr_rmnet_devs--; ++ kfree_rcu(ep, rcu); + } + rmnet_unregister_real_device(real_dev); + unregister_netdevice_many(&list); +--- a/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h ++++ b/drivers/net/ethernet/qualcomm/rmnet/rmnet_config.h +@@ -18,6 +18,7 @@ struct rmnet_endpoint { + u8 mux_id; + struct net_device *egress_dev; + struct hlist_node hlnode; ++ struct rcu_head rcu; + }; + + struct rmnet_egress_agg_params { diff --git a/queue-7.0/series b/queue-7.0/series index 098900599b..676eaf89dd 100644 --- a/queue-7.0/series +++ b/queue-7.0/series @@ -9,3 +9,7 @@ firmware-samsung-acpm-fix-missing-lkmm-barriers-in-sequence-allocator.patch fuse-re-lock-request-before-replacing-page-cache-folio.patch revert-nfsd-defer-sub-object-cleanup-in-export-put-callbacks.patch rdma-bnxt_re-zero-shared-page-before-exposing-to-userspace.patch +bpf-fix-null-pointer-dereference-in-bpf_sk_storage_clone-and-diag-paths.patch +i2c-stub-reject-i2c-block-transfers-with-invalid-length.patch +net-qualcomm-rmnet-fix-endpoint-use-after-free-in-rmnet_dellink.patch +agp-amd64-fix-broken-error-propagation-in-agp_amd64_probe.patch