From: Greg Kroah-Hartman Date: Sun, 29 Mar 2026 12:48:18 +0000 (+0200) Subject: 5.15-stable patches X-Git-Tag: v6.6.131~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a49ee15d39ce66717099296068ffc2452b2b7e82;p=thirdparty%2Fkernel%2Fstable-queue.git 5.15-stable patches added patches: kvm-arm64-discard-pc-update-state-on-vcpu-reset.patch media-mc-v4l2-serialize-reinit-and-reqbufs-with-req_queue_mutex.patch virtio_net-fix-uaf-on-dst_ops-when-iff_xmit_dst_release-is-cleared-and-napi_tx-is-false.patch --- diff --git a/queue-5.15/kvm-arm64-discard-pc-update-state-on-vcpu-reset.patch b/queue-5.15/kvm-arm64-discard-pc-update-state-on-vcpu-reset.patch new file mode 100644 index 0000000000..59151e4c80 --- /dev/null +++ b/queue-5.15/kvm-arm64-discard-pc-update-state-on-vcpu-reset.patch @@ -0,0 +1,81 @@ +From 1744a6ef48b9a48f017e3e1a0d05de0a6978396e Mon Sep 17 00:00:00 2001 +From: Marc Zyngier +Date: Thu, 12 Mar 2026 14:08:50 +0000 +Subject: KVM: arm64: Discard PC update state on vcpu reset + +From: Marc Zyngier + +commit 1744a6ef48b9a48f017e3e1a0d05de0a6978396e upstream. + +Our vcpu reset suffers from a particularly interesting flaw, as it +does not correctly deal with state that will have an effect on the +execution flow out of reset. + +Take the following completely random example, never seen in the wild +and that never resulted in a couple of sleepless nights: /s + +- vcpu-A issues a PSCI_CPU_OFF using the SMC conduit + +- SMC being a trapped instruction (as opposed to HVC which is always + normally executed), we annotate the vcpu as needing to skip the + next instruction, which is the SMC itself + +- vcpu-A is now safely off + +- vcpu-B issues a PSCI_CPU_ON for vcpu-A, providing a starting PC + +- vcpu-A gets reset, get the new PC, and is sent on its merry way + +- right at the point of entering the guest, we notice that a PC + increment is pending (remember the earlier SMC?) + +- vcpu-A skips its first instruction... + +What could possibly go wrong? + +Well, I'm glad you asked. For pKVM as a NV guest, that first instruction +is extremely significant, as it indicates whether the CPU is booting +or resuming. Having skipped that instruction, nothing makes any sense +anymore, and CPU hotplugging fails. + +This is all caused by the decoupling of PC update from the handling +of an exception that triggers such update, making it non-obvious +what affects what when. + +Fix this train wreck by discarding all the PC-affecting state on +vcpu reset. + +Fixes: f5e30680616ab ("KVM: arm64: Move __adjust_pc out of line") +Cc: stable@vger.kernel.org +Reviewed-by: Suzuki K Poulose +Reviewed-by: Joey Gouly +Link: https://patch.msgid.link/20260312140850.822968-1-maz@kernel.org +Signed-off-by: Marc Zyngier +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/kvm/reset.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- a/arch/arm64/kvm/reset.c ++++ b/arch/arm64/kvm/reset.c +@@ -299,6 +299,20 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu + kvm_vcpu_set_be(vcpu); + + *vcpu_pc(vcpu) = target_pc; ++ ++ /* ++ * We may come from a state where either a PC update was ++ * pending (SMC call resulting in PC being increpented to ++ * skip the SMC) or a pending exception. Make sure we get ++ * rid of all that, as this cannot be valid out of reset. ++ * ++ * Note that clearing the exception mask also clears PC ++ * updates, but that's an implementation detail, and we ++ * really want to make it explicit. ++ */ ++ vcpu_clear_flag(vcpu, PENDING_EXCEPTION); ++ vcpu_clear_flag(vcpu, EXCEPT_MASK); ++ vcpu_clear_flag(vcpu, INCREMENT_PC); + vcpu_set_reg(vcpu, 0, reset_state.r0); + } + diff --git a/queue-5.15/media-mc-v4l2-serialize-reinit-and-reqbufs-with-req_queue_mutex.patch b/queue-5.15/media-mc-v4l2-serialize-reinit-and-reqbufs-with-req_queue_mutex.patch new file mode 100644 index 0000000000..4fe33be54b --- /dev/null +++ b/queue-5.15/media-mc-v4l2-serialize-reinit-and-reqbufs-with-req_queue_mutex.patch @@ -0,0 +1,86 @@ +From bef4f4a88b73e4cc550d25f665b8a9952af22773 Mon Sep 17 00:00:00 2001 +From: Yuchan Nam +Date: Fri, 6 Mar 2026 21:52:23 +0900 +Subject: media: mc, v4l2: serialize REINIT and REQBUFS with req_queue_mutex + +From: Yuchan Nam + +commit bef4f4a88b73e4cc550d25f665b8a9952af22773 upstream. + +MEDIA_REQUEST_IOC_REINIT can run concurrently with VIDIOC_REQBUFS(0) +queue teardown paths. This can race request object cleanup against vb2 +queue cancellation and lead to use-after-free reports. + +We already serialize request queueing against STREAMON/OFF with +req_queue_mutex. Extend that serialization to REQBUFS, and also take +the same mutex in media_request_ioctl_reinit() so REINIT is in the +same exclusion domain. + +This keeps request cleanup and queue cancellation from running in +parallel for request-capable devices. + +Fixes: 6093d3002eab ("media: vb2: keep a reference to the request until dqbuf") +Cc: stable@vger.kernel.org +Signed-off-by: Yuchan Nam +Signed-off-by: Sakari Ailus +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/mc/mc-request.c | 5 +++++ + drivers/media/v4l2-core/v4l2-ioctl.c | 5 +++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/media/mc/mc-request.c ++++ b/drivers/media/mc/mc-request.c +@@ -190,6 +190,8 @@ static long media_request_ioctl_reinit(s + struct media_device *mdev = req->mdev; + unsigned long flags; + ++ mutex_lock(&mdev->req_queue_mutex); ++ + spin_lock_irqsave(&req->lock, flags); + if (req->state != MEDIA_REQUEST_STATE_IDLE && + req->state != MEDIA_REQUEST_STATE_COMPLETE) { +@@ -197,6 +199,7 @@ static long media_request_ioctl_reinit(s + "request: %s not in idle or complete state, cannot reinit\n", + req->debug_str); + spin_unlock_irqrestore(&req->lock, flags); ++ mutex_unlock(&mdev->req_queue_mutex); + return -EBUSY; + } + if (req->access_count) { +@@ -204,6 +207,7 @@ static long media_request_ioctl_reinit(s + "request: %s is being accessed, cannot reinit\n", + req->debug_str); + spin_unlock_irqrestore(&req->lock, flags); ++ mutex_unlock(&mdev->req_queue_mutex); + return -EBUSY; + } + req->state = MEDIA_REQUEST_STATE_CLEANING; +@@ -214,6 +218,7 @@ static long media_request_ioctl_reinit(s + spin_lock_irqsave(&req->lock, flags); + req->state = MEDIA_REQUEST_STATE_IDLE; + spin_unlock_irqrestore(&req->lock, flags); ++ mutex_unlock(&mdev->req_queue_mutex); + + return 0; + } +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -2926,13 +2926,14 @@ static long __video_do_ioctl(struct file + vfh = file->private_data; + + /* +- * We need to serialize streamon/off with queueing new requests. ++ * We need to serialize streamon/off/reqbufs with queueing new requests. + * These ioctls may trigger the cancellation of a streaming + * operation, and that should not be mixed with queueing a new + * request at the same time. + */ + if (v4l2_device_supports_requests(vfd->v4l2_dev) && +- (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF)) { ++ (cmd == VIDIOC_STREAMON || cmd == VIDIOC_STREAMOFF || ++ cmd == VIDIOC_REQBUFS)) { + req_queue_lock = &vfd->v4l2_dev->mdev->req_queue_mutex; + + if (mutex_lock_interruptible(req_queue_lock)) diff --git a/queue-5.15/series b/queue-5.15/series index 40d42a49af..31b4559e3d 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -369,3 +369,6 @@ s390-syscalls-add-spectre-boundary-for-syscall-dispatch-table.patch s390-barrier-make-array_index_mask_nospec-__always_inline.patch can-gw-fix-oob-heap-access-in-cgw_csum_crc8_rel.patch cpufreq-conservative-reset-requested_freq-on-limits-change.patch +kvm-arm64-discard-pc-update-state-on-vcpu-reset.patch +media-mc-v4l2-serialize-reinit-and-reqbufs-with-req_queue_mutex.patch +virtio_net-fix-uaf-on-dst_ops-when-iff_xmit_dst_release-is-cleared-and-napi_tx-is-false.patch diff --git a/queue-5.15/virtio_net-fix-uaf-on-dst_ops-when-iff_xmit_dst_release-is-cleared-and-napi_tx-is-false.patch b/queue-5.15/virtio_net-fix-uaf-on-dst_ops-when-iff_xmit_dst_release-is-cleared-and-napi_tx-is-false.patch new file mode 100644 index 0000000000..1a44df7a45 --- /dev/null +++ b/queue-5.15/virtio_net-fix-uaf-on-dst_ops-when-iff_xmit_dst_release-is-cleared-and-napi_tx-is-false.patch @@ -0,0 +1,90 @@ +From ba8bda9a0896746053aa97ac6c3e08168729172c Mon Sep 17 00:00:00 2001 +From: xietangxin +Date: Thu, 12 Mar 2026 10:54:06 +0800 +Subject: virtio_net: Fix UAF on dst_ops when IFF_XMIT_DST_RELEASE is cleared and napi_tx is false + +From: xietangxin + +commit ba8bda9a0896746053aa97ac6c3e08168729172c upstream. + +A UAF issue occurs when the virtio_net driver is configured with napi_tx=N +and the device's IFF_XMIT_DST_RELEASE flag is cleared +(e.g., during the configuration of tc route filter rules). + +When IFF_XMIT_DST_RELEASE is removed from the net_device, the network stack +expects the driver to hold the reference to skb->dst until the packet +is fully transmitted and freed. In virtio_net with napi_tx=N, +skbs may remain in the virtio transmit ring for an extended period. + +If the network namespace is destroyed while these skbs are still pending, +the corresponding dst_ops structure has freed. When a subsequent packet +is transmitted, free_old_xmit() is triggered to clean up old skbs. +It then calls dst_release() on the skb associated with the stale dst_entry. +Since the dst_ops (referenced by the dst_entry) has already been freed, +a UAF kernel paging request occurs. + +fix it by adds skb_dst_drop(skb) in start_xmit to explicitly release +the dst reference before the skb is queued in virtio_net. + +Call Trace: + Unable to handle kernel paging request at virtual address ffff80007e150000 + CPU: 2 UID: 0 PID: 6236 Comm: ping Kdump: loaded Not tainted 7.0.0-rc1+ #6 PREEMPT + ... + percpu_counter_add_batch+0x3c/0x158 lib/percpu_counter.c:98 (P) + dst_release+0xe0/0x110 net/core/dst.c:177 + skb_release_head_state+0xe8/0x108 net/core/skbuff.c:1177 + sk_skb_reason_drop+0x54/0x2d8 net/core/skbuff.c:1255 + dev_kfree_skb_any_reason+0x64/0x78 net/core/dev.c:3469 + napi_consume_skb+0x1c4/0x3a0 net/core/skbuff.c:1527 + __free_old_xmit+0x164/0x230 drivers/net/virtio_net.c:611 [virtio_net] + free_old_xmit drivers/net/virtio_net.c:1081 [virtio_net] + start_xmit+0x7c/0x530 drivers/net/virtio_net.c:3329 [virtio_net] + ... + +Reproduction Steps: +NETDEV="enp3s0" + +config_qdisc_route_filter() { + tc qdisc del dev $NETDEV root + tc qdisc add dev $NETDEV root handle 1: prio + tc filter add dev $NETDEV parent 1:0 \ + protocol ip prio 100 route to 100 flowid 1:1 + ip route add 192.168.1.100/32 dev $NETDEV realm 100 +} + +test_ns() { + ip netns add testns + ip link set $NETDEV netns testns + ip netns exec testns ifconfig $NETDEV 10.0.32.46/24 + ip netns exec testns ping -c 1 10.0.32.1 + ip netns del testns +} + +config_qdisc_route_filter + +test_ns +sleep 2 +test_ns + +Fixes: f2fc6a54585a ("[NETNS][IPV6] route6 - move ip6_dst_ops inside the network namespace") +Cc: stable@vger.kernel.org +Signed-off-by: xietangxin +Reviewed-by: Xuan Zhuo +Fixes: 0287587884b1 ("net: better IFF_XMIT_DST_RELEASE support") +Link: https://patch.msgid.link/20260312025406.15641-1-xietangxin@yeah.net +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/virtio_net.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -1831,6 +1831,7 @@ static netdev_tx_t start_xmit(struct sk_ + /* Don't wait up for transmitted skbs to be freed. */ + if (!use_napi) { + skb_orphan(skb); ++ skb_dst_drop(skb); + nf_reset_ct(skb); + } +