VYPR
Unrated severityNVD Advisory· Published Jun 9, 2026

CVE-2026-46321

CVE-2026-46321

Description

Linux kernel tun/xdp vulnerability allows local attackers to cause an OOM panic by leaking memory via crafted short frames.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Linux kernel tun/xdp vulnerability allows local attackers to cause an OOM panic by leaking memory via crafted short frames.

Vulnerability

The Linux kernel's tun_xdp_one() function fails to free an allocated page when rejecting frames shorter than ETH_HLEN. This occurs when a tun/tap device is attached as a vhost-net backend and receives TX descriptors with a length less than ETH_HLEN after accounting for the virtio-net header. Affected versions are not explicitly stated but the fix is present in the provided reference [1].

Exploitation

A local attacker with the ability to open /dev/net/tun and /dev/vhost-net can exploit this vulnerability. The attacker must attach a tun/tap device as the vhost-net backend and then repeatedly send TX descriptors whose effective length (total length minus virtio-net header) is below ETH_HLEN. This triggers the faulty code path in tun_xdp_one().

Impact

Successful exploitation leads to a memory leak, where each short frame processed leaks page-frag chunks. A tight submission loop can exhaust host memory, ultimately causing an Out-Of-Memory (OOM) panic and a denial of service on the system.

Mitigation

The vulnerability is resolved in the Linux kernel version associated with the commit 98c67be9eb9de72465a071949e84a3cdb8fab5a3 [1]. No workarounds are disclosed in the available references. The reference provided does not contain information about EOL status or KEV listing.

AI Insight generated on Jun 9, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

8
f4feb1e20058

tun: free page on short-frame rejection in tun_xdp_one()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitWeiming ShiMay 20, 2026Fixed in 7.1-rc6via kernel-cna
1 file changed · +3 2
  • drivers/net/tun.c+3 2 modified
    diff --git a/drivers/net/tun.c b/drivers/net/tun.c
    index b183189f18535..f594360d66d65 100644
    --- a/drivers/net/tun.c
    +++ b/drivers/net/tun.c
    @@ -2394,8 +2394,10 @@ static int tun_xdp_one(struct tun_struct *tun,
     	bool skb_xdp = false;
     	struct page *page;
     
    -	if (unlikely(datasize < ETH_HLEN))
    +	if (unlikely(datasize < ETH_HLEN)) {
    +		put_page(virt_to_head_page(xdp->data));
     		return -EINVAL;
    +	}
     
     	xdp_prog = rcu_dereference(tun->xdp_prog);
     	if (xdp_prog) {
    -- 
    cgit 1.3-korg
    
    
    
69863ff2720a

tun: free page on short-frame rejection in tun_xdp_one()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitWeiming ShiMay 20, 2026Fixed in 6.12.93via kernel-cna
1 file changed · +3 2
  • drivers/net/tun.c+3 2 modified
    diff --git a/drivers/net/tun.c b/drivers/net/tun.c
    index fb9d425eff8c1..19c33d21bab94 100644
    --- a/drivers/net/tun.c
    +++ b/drivers/net/tun.c
    @@ -2459,8 +2459,10 @@ static int tun_xdp_one(struct tun_struct *tun,
     	bool skb_xdp = false;
     	struct page *page;
     
    -	if (unlikely(datasize < ETH_HLEN))
    +	if (unlikely(datasize < ETH_HLEN)) {
    +		put_page(virt_to_head_page(xdp->data));
     		return -EINVAL;
    +	}
     
     	xdp_prog = rcu_dereference(tun->xdp_prog);
     	if (xdp_prog) {
    -- 
    cgit 1.3-korg
    
    
    
37a1c268c2c8

tun: free page on short-frame rejection in tun_xdp_one()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitWeiming ShiMay 20, 2026Fixed in 6.18.35via kernel-cna
1 file changed · +3 2
  • drivers/net/tun.c+3 2 modified
    diff --git a/drivers/net/tun.c b/drivers/net/tun.c
    index 8192740357a09..afba37965ce3b 100644
    --- a/drivers/net/tun.c
    +++ b/drivers/net/tun.c
    @@ -2392,8 +2392,10 @@ static int tun_xdp_one(struct tun_struct *tun,
     	bool skb_xdp = false;
     	struct page *page;
     
    -	if (unlikely(datasize < ETH_HLEN))
    +	if (unlikely(datasize < ETH_HLEN)) {
    +		put_page(virt_to_head_page(xdp->data));
     		return -EINVAL;
    +	}
     
     	xdp_prog = rcu_dereference(tun->xdp_prog);
     	if (xdp_prog) {
    -- 
    cgit 1.3-korg
    
    
    
98c67be9eb9d

tun: free page on short-frame rejection in tun_xdp_one()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitWeiming ShiMay 20, 2026Fixed in 7.0.12via kernel-cna
1 file changed · +3 2
  • drivers/net/tun.c+3 2 modified
    diff --git a/drivers/net/tun.c b/drivers/net/tun.c
    index c492fda6fc15a..8154d18a2a235 100644
    --- a/drivers/net/tun.c
    +++ b/drivers/net/tun.c
    @@ -2392,8 +2392,10 @@ static int tun_xdp_one(struct tun_struct *tun,
     	bool skb_xdp = false;
     	struct page *page;
     
    -	if (unlikely(datasize < ETH_HLEN))
    +	if (unlikely(datasize < ETH_HLEN)) {
    +		put_page(virt_to_head_page(xdp->data));
     		return -EINVAL;
    +	}
     
     	xdp_prog = rcu_dereference(tun->xdp_prog);
     	if (xdp_prog) {
    -- 
    cgit 1.3-korg
    
    
    
37a1c268c2c8

tun: free page on short-frame rejection in tun_xdp_one()

1 file changed · +3 2
  • drivers/net/tun.c+3 2 modified
    diff --git a/drivers/net/tun.c b/drivers/net/tun.c
    index 8192740357a09..afba37965ce3b 100644
    --- a/drivers/net/tun.c
    +++ b/drivers/net/tun.c
    @@ -2392,8 +2392,10 @@ static int tun_xdp_one(struct tun_struct *tun,
     	bool skb_xdp = false;
     	struct page *page;
     
    -	if (unlikely(datasize < ETH_HLEN))
    +	if (unlikely(datasize < ETH_HLEN)) {
    +		put_page(virt_to_head_page(xdp->data));
     		return -EINVAL;
    +	}
     
     	xdp_prog = rcu_dereference(tun->xdp_prog);
     	if (xdp_prog) {
    -- 
    cgit 1.3-korg
    
    
    
69863ff2720a

tun: free page on short-frame rejection in tun_xdp_one()

1 file changed · +3 2
  • drivers/net/tun.c+3 2 modified
    diff --git a/drivers/net/tun.c b/drivers/net/tun.c
    index fb9d425eff8c1..19c33d21bab94 100644
    --- a/drivers/net/tun.c
    +++ b/drivers/net/tun.c
    @@ -2459,8 +2459,10 @@ static int tun_xdp_one(struct tun_struct *tun,
     	bool skb_xdp = false;
     	struct page *page;
     
    -	if (unlikely(datasize < ETH_HLEN))
    +	if (unlikely(datasize < ETH_HLEN)) {
    +		put_page(virt_to_head_page(xdp->data));
     		return -EINVAL;
    +	}
     
     	xdp_prog = rcu_dereference(tun->xdp_prog);
     	if (xdp_prog) {
    -- 
    cgit 1.3-korg
    
    
    
98c67be9eb9d

tun: free page on short-frame rejection in tun_xdp_one()

1 file changed · +3 2
  • drivers/net/tun.c+3 2 modified
    diff --git a/drivers/net/tun.c b/drivers/net/tun.c
    index c492fda6fc15a..8154d18a2a235 100644
    --- a/drivers/net/tun.c
    +++ b/drivers/net/tun.c
    @@ -2392,8 +2392,10 @@ static int tun_xdp_one(struct tun_struct *tun,
     	bool skb_xdp = false;
     	struct page *page;
     
    -	if (unlikely(datasize < ETH_HLEN))
    +	if (unlikely(datasize < ETH_HLEN)) {
    +		put_page(virt_to_head_page(xdp->data));
     		return -EINVAL;
    +	}
     
     	xdp_prog = rcu_dereference(tun->xdp_prog);
     	if (xdp_prog) {
    -- 
    cgit 1.3-korg
    
    
    
f4feb1e20058

tun: free page on short-frame rejection in tun_xdp_one()

1 file changed · +3 2
  • drivers/net/tun.c+3 2 modified
    diff --git a/drivers/net/tun.c b/drivers/net/tun.c
    index b183189f18535..f594360d66d65 100644
    --- a/drivers/net/tun.c
    +++ b/drivers/net/tun.c
    @@ -2394,8 +2394,10 @@ static int tun_xdp_one(struct tun_struct *tun,
     	bool skb_xdp = false;
     	struct page *page;
     
    -	if (unlikely(datasize < ETH_HLEN))
    +	if (unlikely(datasize < ETH_HLEN)) {
    +		put_page(virt_to_head_page(xdp->data));
     		return -EINVAL;
    +	}
     
     	xdp_prog = rcu_dereference(tun->xdp_prog);
     	if (xdp_prog) {
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"The tun_xdp_one function fails to free allocated memory when rejecting short frames."

Attack vector

A local attacker with the ability to open `/dev/net/tun` and `/dev/vhost-net` can trigger this vulnerability. The attacker must attach a tun/tap device as a vhost-net backend and then submit TX descriptors where the data size, minus the virtio-net header, is less than `ETH_HLEN`. By repeatedly submitting such short frames in a tight loop, the attacker can exhaust host memory, leading to an OOM panic.

Affected code

The vulnerability exists in the `tun_xdp_one` function within `drivers/net/tun.c`. Specifically, the code path where `datasize` is less than `ETH_HLEN` did not free the allocated page before returning an error.

What the fix does

The patch adds a call to `put_page(virt_to_head_page(xdp->data))` within the `if (unlikely(datasize < ETH_HLEN))` block in the `tun_xdp_one` function [patch_id=5354469]. This ensures that the allocated page is freed when a frame shorter than `ETH_HLEN` is rejected, preventing the memory leak. This change aligns the error handling with the existing XDP-program error path.

Preconditions

  • authThe attacker must have local access to the system.
  • configThe attacker must be able to open `/dev/net/tun` and `/dev/vhost-net`.

Generated on Jun 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

1