* [PATCH 0/3] pull request (net): ipsec 2026-02-20
@ 2026-02-20 9:41 Steffen Klassert
2026-02-20 9:41 ` [PATCH 1/3] xfrm6: fix uninitialized saddr in xfrm6_get_saddr() Steffen Klassert
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Steffen Klassert @ 2026-02-20 9:41 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
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.
Please pull or let me know if there are problems.
Thanks!
The following changes since commit fdf3f6800be36377e045e2448087f12132b88d2f:
net: don't touch dev->stats in BPF redirect paths (2026-01-31 12:35:27 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec.git tags/ipsec-2026-02-20
for you to fetch changes up to 4efa91a28576054aae0e6dad9cba8fed8293aef8:
xfrm: always flush state and policy upon NETDEV_UNREGISTER event (2026-02-09 10:28:05 +0100)
----------------------------------------------------------------
ipsec-2026-02-20
----------------------------------------------------------------
Jiayuan Chen (1):
xfrm6: fix uninitialized saddr in xfrm6_get_saddr()
Leon Romanovsky (1):
xfrm: skip templates check for packet offload tunnel mode
Tetsuo Handa (1):
xfrm: always flush state and policy upon NETDEV_UNREGISTER event
net/ipv6/xfrm6_policy.c | 7 +++++--
net/xfrm/xfrm_device.c | 12 +++++++++++-
net/xfrm/xfrm_policy.c | 11 +++++++++--
3 files changed, 25 insertions(+), 5 deletions(-)
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/3] xfrm6: fix uninitialized saddr in xfrm6_get_saddr()
2026-02-20 9:41 [PATCH 0/3] pull request (net): ipsec 2026-02-20 Steffen Klassert
@ 2026-02-20 9:41 ` Steffen Klassert
2026-02-21 0:10 ` patchwork-bot+netdevbpf
2026-02-20 9:41 ` [PATCH 2/3] xfrm: skip templates check for packet offload tunnel mode Steffen Klassert
2026-02-20 9:41 ` [PATCH 3/3] xfrm: always flush state and policy upon NETDEV_UNREGISTER event Steffen Klassert
2 siblings, 1 reply; 5+ messages in thread
From: Steffen Klassert @ 2026-02-20 9:41 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Jiayuan Chen <jiayuan.chen@shopee.com>
xfrm6_get_saddr() does not check the return value of
ipv6_dev_get_saddr(). When ipv6_dev_get_saddr() fails to find a suitable
source address (returns -EADDRNOTAVAIL), saddr->in6 is left
uninitialized, but xfrm6_get_saddr() still returns 0 (success).
This causes the caller xfrm_tmpl_resolve_one() to use the uninitialized
address in xfrm_state_find(), triggering KMSAN warning:
=====================================================
BUG: KMSAN: uninit-value in xfrm_state_find+0x2424/0xa940
xfrm_state_find+0x2424/0xa940
xfrm_resolve_and_create_bundle+0x906/0x5a20
xfrm_lookup_with_ifid+0xcc0/0x3770
xfrm_lookup_route+0x63/0x2b0
ip_route_output_flow+0x1ce/0x270
udp_sendmsg+0x2ce1/0x3400
inet_sendmsg+0x1ef/0x2a0
__sock_sendmsg+0x278/0x3d0
__sys_sendto+0x593/0x720
__x64_sys_sendto+0x130/0x200
x64_sys_call+0x332b/0x3e70
do_syscall_64+0xd3/0xf80
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Local variable tmp.i.i created at:
xfrm_resolve_and_create_bundle+0x3e3/0x5a20
xfrm_lookup_with_ifid+0xcc0/0x3770
=====================================================
Fix by checking the return value of ipv6_dev_get_saddr() and propagating
the error.
Fixes: a1e59abf8249 ("[XFRM]: Fix wildcard as tunnel source")
Reported-by: syzbot+e136d86d34b42399a8b1@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/68bf1024.a70a0220.7a912.02c2.GAE@google.com/T/
Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/ipv6/xfrm6_policy.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 1f19b6f14484..125ea9a5b8a0 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -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, ¶ms->daddr->in6, 0,
- &saddr->in6);
+ err = ipv6_dev_get_saddr(dev_net(dev), dev, ¶ms->daddr->in6, 0,
+ &saddr->in6);
dst_release(dst);
+ if (err)
+ return -EHOSTUNREACH;
return 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/3] xfrm: skip templates check for packet offload tunnel mode
2026-02-20 9:41 [PATCH 0/3] pull request (net): ipsec 2026-02-20 Steffen Klassert
2026-02-20 9:41 ` [PATCH 1/3] xfrm6: fix uninitialized saddr in xfrm6_get_saddr() Steffen Klassert
@ 2026-02-20 9:41 ` Steffen Klassert
2026-02-20 9:41 ` [PATCH 3/3] xfrm: always flush state and policy upon NETDEV_UNREGISTER event Steffen Klassert
2 siblings, 0 replies; 5+ messages in thread
From: Steffen Klassert @ 2026-02-20 9:41 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Leon Romanovsky <leonro@nvidia.com>
In packet offload, hardware is responsible to check templates. The
result of its operation is forwarded through secpath by relevant
drivers. That secpath is actually removed in __xfrm_policy_check2().
In case packet is forwarded, this secpath is reset in RX, but pushed
again to TX where policy is rechecked again against dummy secpath
in xfrm_policy_ok().
Such situation causes to unexpected XfrmInTmplMismatch increase.
As a solution, simply skip template mismatch check.
Fixes: 600258d555f0 ("xfrm: delete intermediate secpath entry in packet offload mode")
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/xfrm/xfrm_policy.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 62486f866975..5428185196a1 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -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;
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 3/3] xfrm: always flush state and policy upon NETDEV_UNREGISTER event
2026-02-20 9:41 [PATCH 0/3] pull request (net): ipsec 2026-02-20 Steffen Klassert
2026-02-20 9:41 ` [PATCH 1/3] xfrm6: fix uninitialized saddr in xfrm6_get_saddr() Steffen Klassert
2026-02-20 9:41 ` [PATCH 2/3] xfrm: skip templates check for packet offload tunnel mode Steffen Klassert
@ 2026-02-20 9:41 ` Steffen Klassert
2 siblings, 0 replies; 5+ messages in thread
From: Steffen Klassert @ 2026-02-20 9:41 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
syzbot is reporting that "struct xfrm_state" refcount is leaking.
unregister_netdevice: waiting for netdevsim0 to become free. Usage count = 2
ref_tracker: netdev@ffff888052f24618 has 1/1 users at
__netdev_tracker_alloc include/linux/netdevice.h:4400 [inline]
netdev_tracker_alloc include/linux/netdevice.h:4412 [inline]
xfrm_dev_state_add+0x3a5/0x1080 net/xfrm/xfrm_device.c:316
xfrm_state_construct net/xfrm/xfrm_user.c:986 [inline]
xfrm_add_sa+0x34ff/0x5fa0 net/xfrm/xfrm_user.c:1022
xfrm_user_rcv_msg+0x58e/0xc00 net/xfrm/xfrm_user.c:3507
netlink_rcv_skb+0x158/0x420 net/netlink/af_netlink.c:2550
xfrm_netlink_rcv+0x71/0x90 net/xfrm/xfrm_user.c:3529
netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
netlink_unicast+0x5aa/0x870 net/netlink/af_netlink.c:1344
netlink_sendmsg+0x8c8/0xdd0 net/netlink/af_netlink.c:1894
sock_sendmsg_nosec net/socket.c:727 [inline]
__sock_sendmsg net/socket.c:742 [inline]
____sys_sendmsg+0xa5d/0xc30 net/socket.c:2592
___sys_sendmsg+0x134/0x1d0 net/socket.c:2646
__sys_sendmsg+0x16d/0x220 net/socket.c:2678
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xcd/0xf80 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
This is because commit d77e38e612a0 ("xfrm: Add an IPsec hardware
offloading API") implemented xfrm_dev_unregister() as no-op despite
xfrm_dev_state_add() from xfrm_state_construct() acquires a reference
to "struct net_device".
I guess that that commit expected that NETDEV_DOWN event is fired before
NETDEV_UNREGISTER event fires, and also assumed that xfrm_dev_state_add()
is called only if (dev->features & NETIF_F_HW_ESP) != 0.
Sabrina Dubroca identified steps to reproduce the same symptoms as below.
echo 0 > /sys/bus/netdevsim/new_device
dev=$(ls -1 /sys/bus/netdevsim/devices/netdevsim0/net/)
ip xfrm state add src 192.168.13.1 dst 192.168.13.2 proto esp \
spi 0x1000 mode tunnel aead 'rfc4106(gcm(aes))' $key 128 \
offload crypto dev $dev dir out
ethtool -K $dev esp-hw-offload off
echo 0 > /sys/bus/netdevsim/del_device
Like these steps indicate, the NETIF_F_HW_ESP bit can be cleared after
xfrm_dev_state_add() acquired a reference to "struct net_device".
Also, xfrm_dev_state_add() does not check for the NETIF_F_HW_ESP bit
when acquiring a reference to "struct net_device".
Commit 03891f820c21 ("xfrm: handle NETDEV_UNREGISTER for xfrm device")
re-introduced the NETDEV_UNREGISTER event to xfrm_dev_event(), but that
commit for unknown reason chose to share xfrm_dev_down() between the
NETDEV_DOWN event and the NETDEV_UNREGISTER event.
I guess that that commit missed the behavior in the previous paragraph.
Therefore, we need to re-introduce xfrm_dev_unregister() in order to
release the reference to "struct net_device" by unconditionally flushing
state and policy.
Reported-by: syzbot+881d65229ca4f9ae8c84@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84
Fixes: d77e38e612a0 ("xfrm: Add an IPsec hardware offloading API")
Cc: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/xfrm/xfrm_device.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 52ae0e034d29..550457e4c4f0 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -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;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/3] xfrm6: fix uninitialized saddr in xfrm6_get_saddr()
2026-02-20 9:41 ` [PATCH 1/3] xfrm6: fix uninitialized saddr in xfrm6_get_saddr() Steffen Klassert
@ 2026-02-21 0:10 ` patchwork-bot+netdevbpf
0 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-02-21 0:10 UTC (permalink / raw)
To: Steffen Klassert; +Cc: davem, kuba, herbert, netdev
Hello:
This series was applied to netdev/net.git (main)
by Steffen Klassert <steffen.klassert@secunet.com>:
On Fri, 20 Feb 2026 10:41:15 +0100 you wrote:
> From: Jiayuan Chen <jiayuan.chen@shopee.com>
>
> xfrm6_get_saddr() does not check the return value of
> ipv6_dev_get_saddr(). When ipv6_dev_get_saddr() fails to find a suitable
> source address (returns -EADDRNOTAVAIL), saddr->in6 is left
> uninitialized, but xfrm6_get_saddr() still returns 0 (success).
>
> [...]
Here is the summary with links:
- [1/3] xfrm6: fix uninitialized saddr in xfrm6_get_saddr()
https://git.kernel.org/netdev/net/c/1799d8abeabc
- [2/3] xfrm: skip templates check for packet offload tunnel mode
https://git.kernel.org/netdev/net/c/0a4524bc6988
- [3/3] xfrm: always flush state and policy upon NETDEV_UNREGISTER event
https://git.kernel.org/netdev/net/c/4efa91a28576
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-02-21 0:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-20 9:41 [PATCH 0/3] pull request (net): ipsec 2026-02-20 Steffen Klassert
2026-02-20 9:41 ` [PATCH 1/3] xfrm6: fix uninitialized saddr in xfrm6_get_saddr() Steffen Klassert
2026-02-21 0:10 ` patchwork-bot+netdevbpf
2026-02-20 9:41 ` [PATCH 2/3] xfrm: skip templates check for packet offload tunnel mode Steffen Klassert
2026-02-20 9:41 ` [PATCH 3/3] xfrm: always flush state and policy upon NETDEV_UNREGISTER event Steffen Klassert
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox