ipsec-2026-02-20

-----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEH7ZpcWbFyOOp6OJbrB3Eaf9PW7cFAmmYIsoACgkQrB3Eaf9P
 W7d4HQ/8DblZh6FcGi+/XR9jSfqWjFRTU37FHrgpveOtCcoXqYYC8OwKqYnqRABh
 rKgynAjrzKLKYUNFEOZVEYRb/ohKdZ9WlxAOK9ezSlFoEp7W3jfB8hkYv98vl45E
 8gw6dqRZt2J9hKa0mcyBPosKZ43yShNWEVktQWpoFOL4fy6fCZVpgOwMSzEr8oRV
 56AjvHjM8oFDP3BEDPeCGayzC8GFlER8fc79sUZNDpRr5OQtGo1NoceyUaGIJxZS
 d7g7WPgbewbfpx+IQavhmfiLYWXNwPal8aTtUNIZclPVB75+efkDNWf89O7ZGlZE
 5LLo2Ix2oG/IP3EmKA42IqO6Rx7T6N89kK3AwXeEVP1BciwYhYch0L0ts5XdU6nG
 A9fQQ+qNukVK8F65dk32zSTStAsGUh/WxgAgY0jnbDwJlOsVwf4B9CEcTC3RavtS
 OvW2vIVtBYq3xdLh3DoUMxvLj+LIk6WOuicO4QHk+qDqHD0/gbkxVbb7hpXALOvc
 CCf5/+PG6s2uatIlsOJp+hg8BAQqG1s8vcvfHYpfBzLjJhTA4cem2pIFchMeIgei
 f25W5vzftMNm+sZejAhCzBwDkrEegNpjE6BbyQ4psYh44QIyRzveDVIHdVZmgpv6
 nXCcL2K9jgkdUG4TLOj1FYTp/cWhNOGGyh6gVCVH+mupbdyTd6A=
 =Aa4a
 -----END PGP SIGNATURE-----

Merge tag 'ipsec-2026-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec

Steffen Klassert says:

====================
pull request (net): ipsec 2026-02-20

1) Check the value of ipv6_dev_get_saddr() to fix an
   uninitialized saddr in xfrm6_get_saddr().
   From Jiayuan Chen.

2) Skip the templates check for packet offload in tunnel
   mode. Is was already done by the hardware and causes
   an unexpected XfrmInTmplMismatch increase.
   From Leon Romanovsky.

3) Fix a unregister_netdevice stall due to not dropped
   refcounts by always flushing xfrm state and policy
   on a NETDEV_UNREGISTER event.
   From Tetsuo Handa.

* tag 'ipsec-2026-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec:
  xfrm: always flush state and policy upon NETDEV_UNREGISTER event
  xfrm: skip templates check for packet offload tunnel mode
  xfrm6: fix uninitialized saddr in xfrm6_get_saddr()
====================

Link: https://patch.msgid.link/20260220094133.14219-1-steffen.klassert@secunet.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2026-02-20 15:57:55 -08:00
commit 0aebd81fa8
3 changed files with 25 additions and 5 deletions

View file

@ -57,6 +57,7 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr,
struct dst_entry *dst;
struct net_device *dev;
struct inet6_dev *idev;
int err;
dst = xfrm6_dst_lookup(params);
if (IS_ERR(dst))
@ -68,9 +69,11 @@ static int xfrm6_get_saddr(xfrm_address_t *saddr,
return -EHOSTUNREACH;
}
dev = idev->dev;
ipv6_dev_get_saddr(dev_net(dev), dev, &params->daddr->in6, 0,
&saddr->in6);
err = ipv6_dev_get_saddr(dev_net(dev), dev, &params->daddr->in6, 0,
&saddr->in6);
dst_release(dst);
if (err)
return -EHOSTUNREACH;
return 0;
}

View file

@ -544,6 +544,14 @@ static int xfrm_dev_down(struct net_device *dev)
return NOTIFY_DONE;
}
static int xfrm_dev_unregister(struct net_device *dev)
{
xfrm_dev_state_flush(dev_net(dev), dev, true);
xfrm_dev_policy_flush(dev_net(dev), dev, true);
return NOTIFY_DONE;
}
static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
@ -556,8 +564,10 @@ static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void
return xfrm_api_check(dev);
case NETDEV_DOWN:
case NETDEV_UNREGISTER:
return xfrm_dev_down(dev);
case NETDEV_UNREGISTER:
return xfrm_dev_unregister(dev);
}
return NOTIFY_DONE;
}

View file

@ -3801,8 +3801,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
struct xfrm_tmpl *tp[XFRM_MAX_DEPTH];
struct xfrm_tmpl *stp[XFRM_MAX_DEPTH];
struct xfrm_tmpl **tpp = tp;
int i, k = 0;
int ti = 0;
int i, k;
sp = skb_sec_path(skb);
if (!sp)
@ -3828,6 +3828,12 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
tpp = stp;
}
if (pol->xdo.type == XFRM_DEV_OFFLOAD_PACKET && sp == &dummy)
/* This policy template was already checked by HW
* and secpath was removed in __xfrm_policy_check2.
*/
goto out;
/* For each tunnel xfrm, find the first matching tmpl.
* For each tmpl before that, find corresponding xfrm.
* Order is _important_. Later we will implement
@ -3837,7 +3843,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
* verified to allow them to be skipped in future policy
* checks (e.g. nested tunnels).
*/
for (i = xfrm_nr-1, k = 0; i >= 0; i--) {
for (i = xfrm_nr - 1; i >= 0; i--) {
k = xfrm_policy_ok(tpp[i], sp, k, family, if_id);
if (k < 0) {
if (k < -1)
@ -3853,6 +3859,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
goto reject;
}
out:
xfrm_pols_put(pols, npols);
sp->verified_cnt = k;