From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-m16.yeah.net (mail-m16.yeah.net [1.95.21.14]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E6F2264A97 for ; Tue, 10 Mar 2026 06:37:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=1.95.21.14 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773124627; cv=none; b=ZI1HjQTCb/SmGG25f1bvSoYYY+879WAv/XldfQOqHqNzKjK+mHmySD4sgz2bdWo9Gf/mBya8/FkdbERl+0DznIDWMqZ9xZeikiSU4C4lgLh8SBwdoNgDuL4RY2rWH1kN1w/l9Xs6QcjODCn16qVorQPMD7nZs8bfXDlYgXv9wRc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773124627; c=relaxed/simple; bh=XsmaA0lgW9uGpln6K/yqwvcGtYGkgY1f8puoczaMf3A=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=JAQcUgtfeIHkH2HwSyerxBORWxG1u9+hqXUxT//2N8nHk8Cze2IN1CWp6J8N67dOQbsd63A28B63hwYY6aSPbd7behJQbbTOdxSOHKmsE3/SjTIS3x9RA+/L7neH1x7ZWnkuitZ9rW1d2n5s5YlN7RB6xfi9NL3umTV3SC7J/Ts= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=yeah.net; spf=pass smtp.mailfrom=yeah.net; dkim=pass (1024-bit key) header.d=yeah.net header.i=@yeah.net header.b=Ul5dS0B1; arc=none smtp.client-ip=1.95.21.14 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=yeah.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=yeah.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=yeah.net header.i=@yeah.net header.b="Ul5dS0B1" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yeah.net; s=s110527; h=Message-ID:Date:MIME-Version:Subject:To:From: Content-Type; bh=dwKmeyTuqCGuHp07HiwP0COMuXzDZ1A+iREkHHcf93g=; b=Ul5dS0B1DJyDlSJCXsWy5jb2LC02eklxf4xV92fU+Or7WdswrQMD1ScrrG5yr4 ECiwekzGu7oaL2WSXwP7p97AIh2eh+e0ppd5MbTLlbdbS1YiyXnscld5SrPnO533 ndO1ywy7lwzOu7LQxC00a+ldnMKYX7ICDhog7M6aovbXA= Received: from [7.247.167.131] (unknown []) by gzsmtp2 (Coremail) with UTF8SMTPA id Ms8vCgDnDbDsu69pr6x0Ag--.32698S2; Tue, 10 Mar 2026 14:36:29 +0800 (CST) Message-ID: Date: Tue, 10 Mar 2026 14:36:27 +0800 Precedence: bulk X-Mailing-List: virtualization@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] virtio_net: Fix UAF on dst_ops when IFF_XMIT_DST_RELEASE is cleared and napi_tx is false To: Eric Dumazet Cc: "Michael S . Tsirkin" , Jason Wang , "David S . Miller" , Jakub Kicinski , Paolo Abeni , Andrew Lunn , Xuan Zhuo , =?UTF-8?Q?Eugenio_P=C3=A9rez?= , netdev@vger.kernel.org, virtualization@lists.linux.dev, linux-kernel@vger.kernel.org References: <20260307035110.7121-1-xietangxin@yeah.net> From: xietangxin In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-CM-TRANSID:Ms8vCgDnDbDsu69pr6x0Ag--.32698S2 X-Coremail-Antispam: 1Uf129KBjvJXoWxXw4rXFy8Zw4DGryxJFWkJFb_yoWrJF1xpr 4FyFW5Xr4Utr17Aan3XF4DWryYvan3Gw43Grs0gr4fCrZ8uF15JF129ryjgFWDZrs5uryj vw4Fvr12gr90vFJanT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07jOKsUUUUUU= X-CM-SenderInfo: x0lh3tpqj0x0o61htxgoqh3/1tbiIg1wpGmvu+3A5AAA3P On 3/7/2026 12:15 PM, Eric Dumazet wrote: > On Sat, Mar 7, 2026 at 4:52 AM xietangxin wrote: >> >> 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 >> >> Signed-off-by: xietangxin >> --- >> drivers/net/virtio_net.c | 1 + >> 1 file changed, 1 insertion(+) >> >> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c >> index 72d6a9c6a..5b13a61b3 100644 >> --- a/drivers/net/virtio_net.c >> +++ b/drivers/net/virtio_net.c >> @@ -3351,6 +3351,7 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) >> /* Don't wait up for transmitted skbs to be freed. */ >> if (!use_napi) { >> skb_orphan(skb); >> + skb_dst_drop(skb); >> nf_reset_ct(skb); >> } > > This probably could skb_release_head_state() at this point. > > Thanks. Hi Eric, Thanks for the suggestion. I have verified that calling skb_release_head_state() in the virtio_net does indeed fix the UAF issue. However, skb_release_head_state() is currently a non-exported symbol. Since virtio_net can be built as a module, using it would require exporting. Given that this issue currently only affects virtio_net, I am concerned whether exporting such a core internal function is appropriate. Best regards, Tangxin Xie