]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.12-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Jun 2026 10:21:05 +0000 (11:21 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Jun 2026 10:21:05 +0000 (11:21 +0100)
added patches:
agp-amd64-fix-broken-error-propagation-in-agp_amd64_probe.patch
i2c-stub-reject-i2c-block-transfers-with-invalid-length.patch
net-qualcomm-rmnet-fix-endpoint-use-after-free-in-rmnet_dellink.patch

queue-6.12/agp-amd64-fix-broken-error-propagation-in-agp_amd64_probe.patch [new file with mode: 0644]
queue-6.12/i2c-stub-reject-i2c-block-transfers-with-invalid-length.patch [new file with mode: 0644]
queue-6.12/net-qualcomm-rmnet-fix-endpoint-use-after-free-in-rmnet_dellink.patch [new file with mode: 0644]
queue-6.12/series

diff --git a/queue-6.12/agp-amd64-fix-broken-error-propagation-in-agp_amd64_probe.patch b/queue-6.12/agp-amd64-fix-broken-error-propagation-in-agp_amd64_probe.patch
new file mode 100644 (file)
index 0000000..acbd322
--- /dev/null
@@ -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 <lukas@wunner.de>
+Reviewed-by: Lukas Wunner <lukas@wunner.de>
+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 <gregkh@linuxfoundation.org>
+---
+ 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-6.12/i2c-stub-reject-i2c-block-transfers-with-invalid-length.patch b/queue-6.12/i2c-stub-reject-i2c-block-transfers-with-invalid-length.patch
new file mode 100644 (file)
index 0000000..a602798
--- /dev/null
@@ -0,0 +1,71 @@
+From 6036b5067a8199ba7a2dc7b377d4b9dd276d5f9e Mon Sep 17 00:00:00 2001
+From: Weiming Shi <bestswngs@gmail.com>
+Date: Wed, 15 Apr 2026 01:23:39 +0800
+Subject: i2c: stub: Reject I2C block transfers with invalid length
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+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:
+  <TASK>
+  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)
+  </TASK>
+
+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 <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Reviewed-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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-6.12/net-qualcomm-rmnet-fix-endpoint-use-after-free-in-rmnet_dellink.patch b/queue-6.12/net-qualcomm-rmnet-fix-endpoint-use-after-free-in-rmnet_dellink.patch
new file mode 100644 (file)
index 0000000..ef6c096
--- /dev/null
@@ -0,0 +1,87 @@
+From d00c953a8f69921f484b629801766da68f27f658 Mon Sep 17 00:00:00 2001
+From: Weiming Shi <bestswngs@gmail.com>
+Date: Thu, 14 May 2026 05:25:12 -0700
+Subject: net: qualcomm: rmnet: fix endpoint use-after-free in rmnet_dellink()
+
+From: Weiming Shi <bestswngs@gmail.com>
+
+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:
+   <TASK>
+   __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)
+   </TASK>
+
+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 <xmei5@asu.edu>
+Signed-off-by: Weiming Shi <bestswngs@gmail.com>
+Link: https://patch.msgid.link/20260514122511.3083479-2-bestswngs@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -210,8 +210,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);
+@@ -235,9 +235,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 {
index ca9948c2fbd04e3f46b0c614b59f3e51a5d1036f..a214c36f55402e9ec0aef037b45774bba210e6d6 100644 (file)
@@ -25,3 +25,6 @@ debugobjects-use-ld_wait_config-instead-of-ld_wait_s.patch
 debugobjects-do-not-fill_pool-if-pi_blocked_on.patch
 debugobjects-dont-call-fill_pool-in-early-boot-hardi.patch
 rdma-bnxt_re-zero-shared-page-before-exposing-to-userspace.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