VYPR
Unrated severityNVD Advisory· Published May 28, 2026

CVE-2026-46172

CVE-2026-46172

Description

In the Linux kernel, the following vulnerability has been resolved:

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

xfrm6_rcv_encap() performs an IPv6 route lookup when the skb does not already have a dst attached. ip6_route_input_lookup() returns a referenced dst entry even when the lookup resolves to an error route.

If dst->error is set, xfrm6_rcv_encap() drops the skb without attaching the dst to the skb and without releasing the reference returned by the lookup. Repeated packets hitting this path therefore leak dst entries.

Release the dst before jumping to the drop path.

AI Insight

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

A route lookup reference leak in Linux kernel's xfrm6_rcv_encap() can exhaust system memory; fixed by releasing the dst on error.

Vulnerability

In the Linux kernel, xfrm6_rcv_encap() (part of the IPv6 XFRM stack) performs a route lookup via ip6_route_input_lookup() when the socket buffer (skb) does not already have a dst attached. This lookup returns a referenced dst entry even if the route has an error condition (i.e., dst->error is non-zero). The function then drops the skb without releasing that reference, causing a memory leak of dst entries on each error path triggered by such packets. The issue affects Linux kernel versions prior to the inclusion of commit c2efc4956981066df2fef1cc77391b523db6d8e4. [1]

Exploitation

An attacker must be able to send crafted IPv6 packets to a system with XFRM processing enabled (e.g., using IPsec) such that the skb arrives at xfrm6_rcv_encap() without a pre-attached dst. No authentication or special privileges are needed; the attacker only needs network access to the target. The repeated triggering of the error path—sending many packets that cause a route lookup failure—will gradually exhaust kernel memory allocated for dst entries. [1]

Impact

A remote attacker can cause a denial-of-service (DoS) by exhausting system memory through cumulative dst entry leaks. This can lead to system instability or service disruption. There is no confidentiality or integrity impact. The privilege level required is none (network-only access). [1]

Mitigation

The fix is contained in the Linux kernel commit c2efc4956981066df2fef1cc77391b523db6d8e4, which releases the dst reference before jumping to the drop path when dst->error is set. This commit was included in kernel releases starting from 2025-10-29 (per stable tag). Users should update their kernel to the fixed version. No workaround is documented. [1]

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

Affected products

2

Patches

10
bc0fcb9823cd

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYilin ZhuApr 12, 2026Fixed in 7.1-rc3via kernel-cna
2 files changed · +6 4
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
c2efc4956981

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYilin ZhuApr 12, 2026Fixed in 6.6.140via kernel-cna
2 files changed · +6 4
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
554c9b090c8a

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYilin ZhuApr 12, 2026Fixed in 6.12.88via kernel-cna
2 files changed · +6 4
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
9d5047782f9b

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYilin ZhuApr 12, 2026Fixed in 6.18.30via kernel-cna
2 files changed · +6 4
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
6a5eec0a2a0e

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitYilin ZhuApr 12, 2026Fixed in 7.0.7via kernel-cna
2 files changed · +6 4
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
bc0fcb9823cd

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

2 files changed · +6 4
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
554c9b090c8a

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

2 files changed · +6 4
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
6a5eec0a2a0e

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

2 files changed · +6 4
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
9d5047782f9b

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

2 files changed · +6 4
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
c2efc4956981

ipv6: xfrm6: release dst on error in xfrm6_rcv_encap()

2 files changed · +6 4
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    
  • net/ipv6/xfrm6_protocol.c+3 2 modified
    diff --git a/net/ipv6/xfrm6_protocol.c b/net/ipv6/xfrm6_protocol.c
    index ea2f805d3b014c..9b586fcec4850b 100644
    --- a/net/ipv6/xfrm6_protocol.c
    +++ b/net/ipv6/xfrm6_protocol.c
    @@ -88,8 +88,10 @@ int xfrm6_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
     
     		dst = ip6_route_input_lookup(dev_net(skb->dev), skb->dev, &fl6,
     					     skb, flags);
    -		if (dst->error)
    +		if (dst->error) {
    +			dst_release(dst);
     			goto drop;
    +		}
     		skb_dst_set(skb, dst);
     	}
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing dst_release() call before dropping the skb when ip6_route_input_lookup() returns an error route, causing a reference-count leak."

Attack vector

An attacker sends UDP-encapsulated ESP packets (IPv6) to a host that performs xfrm6_rcv_encap() processing. When the skb has no dst attached, the function calls ip6_route_input_lookup() which returns a referenced dst entry even for error routes. If dst->error is set, the skb is dropped without releasing the dst reference. Repeated packets hitting this code path cause a gradual leak of dst entries, eventually exhausting kernel memory or triggering resource-starvation conditions.

Affected code

The vulnerable function is xfrm6_rcv_encap() in net/ipv6/xfrm6_protocol.c. The fault lies in the code path where ip6_route_input_lookup() returns a dst entry with dst->error set, and the function jumps to the drop label without calling dst_release() on that entry.

What the fix does

The patch adds a dst_release(dst) call inside the error-check block before jumping to the drop label [patch_id=2898077]. This ensures the reference returned by ip6_route_input_lookup() is properly decremented when the route lookup yields an error, preventing the reference-count leak. The fix is minimal: it wraps the existing `if (dst->error)` check in braces and inserts the release call.

Preconditions

  • configThe system must be processing UDP-encapsulated ESP (IPsec) packets over IPv6 via xfrm6_rcv_encap().
  • inputThe received skb must not already have a dst attached, triggering the route lookup path.
  • inputThe route lookup must resolve to an error route (dst->error != 0).

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

References

5

News mentions

0

No linked articles in our index yet.