From: Steffen Klassert <steffen.klassert@secunet.com>
To: David Miller <davem@davemloft.net>, Jakub Kicinski <kuba@kernel.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
Steffen Klassert <steffen.klassert@secunet.com>,
<netdev@vger.kernel.org>
Subject: [PATCH 06/10] xfrm: reject optional IPTFS templates in outbound policies
Date: Fri, 10 Jul 2026 11:03:19 +0200 [thread overview]
Message-ID: <20260710090349.343389-7-steffen.klassert@secunet.com> (raw)
In-Reply-To: <20260710090349.343389-1-steffen.klassert@secunet.com>
From: Antony Antony <antony.antony@secunet.com>
syzbot reported a stack-out-of-bounds read in xfrm_state_find()
which flows from xfrm_tmpl_resolve_one().
Commit 3d776e31c841 ("xfrm: Reject optional tunnel/BEET mode
templates in outbound policies") disallowed optional tunnel and
BEET in outbound policies to prevent this. Later when IPTFS
added, it was not covered by that fix and can still trigger
the out-of-bounds read;
Extend the check to disallow optional IPTFS in outbound policies
as well. IPTFS should be identical to tunnel mode.
IN and FWD policies are not affected: xfrm_tmpl_resolve_one()
is only reachable via the outbound path.
Reproducer, before:
ip link add dummy0 type dummy
ip link set dummy0 up
ip addr add 10.1.1.1/24 dev dummy0
ip xfrm policy add src 10.1.1.1/32 dst 10.1.1.2/32 dir out tmpl
src fc00::dead:1 dst fc00::dead:2 proto esp reqid 1 mode iptfs
level use tmpl src fc00::dead:1 dst fc00::dead:2 proto esp reqid
2 mode transport
ping -W 1 -c 1 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
[ 64.168420] ==================================================================
[ 64.169977] BUG: KASAN: stack-out-of-bounds in __xfrm6_addr_hash+0x11e/0x170
[ 64.169977] Read of size 4 at addr ffff88800e1ffd20 by task ping/2844
[ 64.169977] CPU: 2 UID: 0 PID: 2844 Comm: ping Not tainted 7.1.0-rc7-00180-geb23b588430a #98 PREEMPT(full)
[ 64.169977] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 64.169977] Call Trace:
[ 64.169977] <TASK>
[ 64.169977] dump_stack_lvl+0x47/0x70
[ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170
[ 64.169977] print_report+0x152/0x4b0
[ 64.169977] ? ksys_mmap_pgoff+0x6d/0xa0
[ 64.169977] ? entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 64.169977] ? rcu_read_unlock_sched+0xa/0x20
[ 64.169977] ? __virt_addr_valid+0x21b/0x230
[ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170
[ 64.169977] kasan_report+0xa8/0xd0
[ 64.169977] ? __xfrm6_addr_hash+0x11e/0x170
[ 64.169977] __xfrm6_addr_hash+0x11e/0x170
[ 64.169977] __xfrm_dst_hash+0x24/0xc0
[ 64.169977] xfrm_state_find+0xa2d/0x2f90
[ 64.169977] ? __pfx_xfrm_state_find+0x10/0x10
[ 64.169977] ? __pfx_ftrace_graph_ret_addr+0x10/0x10
[ 64.169977] ? __pfx_ftrace_graph_ret_addr+0x10/0x10
[ 64.169977] xfrm_tmpl_resolve_one+0x210/0x570
[ 64.169977] ? __pfx_xfrm_tmpl_resolve_one+0x10/0x10
[ 64.169977] ? __pfx_stack_trace_consume_entry+0x10/0x10
[ 64.169977] ? kernel_text_address+0x5b/0x80
[ 64.169977] ? __kernel_text_address+0xe/0x30
[ 64.169977] ? unwind_get_return_address+0x5e/0x90
[ 64.169977] ? arch_stack_walk+0x8c/0xe0
[ 64.169977] xfrm_tmpl_resolve+0x130/0x200
[ 64.169977] ? __pfx_xfrm_tmpl_resolve+0x10/0x10
[ 64.169977] ? __pfx_xfrm_policy_inexact_lookup_rcu+0x10/0x10
[ 64.169977] ? __refcount_add_not_zero.constprop.0+0xb2/0x110
[ 64.169977] ? __pfx___refcount_add_not_zero.constprop.0+0x10/0x10
[ 64.169977] xfrm_resolve_and_create_bundle+0xd5/0x310
[ 64.169977] ? __pfx_xfrm_resolve_and_create_bundle+0x10/0x10
[ 64.169977] ? __pfx_xfrm_policy_lookup_bytype+0x10/0x10
[ 64.169977] ? __pfx_xfrm_policy_lookup_bytype+0x10/0x10
[ 64.169977] xfrm_lookup_with_ifid+0x3d8/0xb80
[ 64.169977] ? __pfx_xfrm_lookup_with_ifid+0x10/0x10
[ 64.169977] ? ip_route_output_key_hash+0xc6/0x110
[ 64.169977] ? kasan_save_track+0x10/0x30
[ 64.169977] xfrm_lookup_route+0x18/0xe0
[ 64.169977] ip4_datagram_release_cb+0x4c9/0x530
[ 64.169977] ? __pfx_ip4_datagram_release_cb+0x10/0x10
[ 64.169977] ? do_raw_spin_lock+0x71/0xc0
[ 64.169977] ? __pfx_do_raw_spin_lock+0x10/0x10
[ 64.169977] release_sock+0xb0/0x170
[ 64.169977] udp_connect+0x43/0x50
[ 64.169977] __sys_connect+0xa6/0x100
[ 64.169977] ? alloc_fd+0x2e9/0x300
[ 64.169977] ? __pfx___sys_connect+0x10/0x10
[ 64.169977] ? preempt_latency_start+0x1f/0x70
[ 64.169977] ? fd_install+0x7e/0x150
[ 64.169977] ? rcu_read_unlock_sched+0xa/0x20
[ 64.169977] ? __sys_socket+0xdf/0x130
[ 64.169977] ? __pfx___sys_socket+0x10/0x10
[ 64.169977] ? vma_refcount_put+0x43/0xa0
[ 64.169977] __x64_sys_connect+0x7e/0x90
[ 64.169977] do_syscall_64+0x11b/0x2b0
[ 64.169977] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 64.169977] RIP: 0033:0x7f4851ecb570
[ 64.169977] Code: 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 80 3d f9 ca 0d 00 00 74 17 b8 2a 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 48 83 ec 18 89 54
[ 64.169977] RSP: 002b:00007ffc830e3498 EFLAGS: 00000202 ORIG_RAX: 000000000000002a
[ 64.169977] RAX: ffffffffffffffda RBX: 00007ffc830e34d0 RCX: 00007f4851ecb570
[ 64.169977] RDX: 0000000000000010 RSI: 00007ffc830e34d0 RDI: 0000000000000005
[ 64.169977] RBP: 0000000000000000 R08: 0000000000000003 R09: 0000000000000000
[ 64.169977] R10: 0000000000000006 R11: 0000000000000202 R12: 0000000000000005
[ 64.169977] R13: 0000000000000000 R14: 00005619a863f340 R15: 0000000000000000
[ 64.169977] </TASK>
[ 64.169977] The buggy address belongs to stack of task ping/2844
[ 64.169977] and is located at offset 88 in frame:
[ 64.169977] ip4_datagram_release_cb+0x0/0x530
[ 64.169977] This frame has 1 object:
[ 64.169977] [32, 88) 'fl4'
[ 64.169977] The buggy address belongs to the physical page:
[ 64.169977] page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xe1ff
[ 64.169977] flags: 0x4000000000000000(zone=1)
[ 64.169977] raw: 4000000000000000 0000000000000000 ffffea0000387fc8 0000000000000000
[ 64.169977] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
[ 64.169977] page dumped because: kasan: bad access detected
[ 64.169977] Memory state around the buggy address:
[ 64.169977] ffff88800e1ffc00: f2 f2 00 00 f3 f3 00 00 00 00 00 00 00 00 00 00
[ 64.169977] ffff88800e1ffc80: 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 00
[ 64.169977] >ffff88800e1ffd00: 00 00 00 00 f3 f3 f3 f3 f3 00 00 00 00 00 00 00
[ 64.169977] ^
[ 64.169977] ffff88800e1ffd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
[ 64.169977] ffff88800e1ffe00: f1 f1 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 64.169977] ==================================================================
[ 64.245153] Disabling lock debugging due to kernel taint
After the fix:
ip xfrm policy add src 10.1.1.1/32 dst 10.1.1.2/32 dir out tmpl \
src fc00::dead:1 dst fc00::dead:2 proto esp reqid 1 mode iptfs \
level use tmpl src fc00::dead:1 dst fc00::dead:2 proto esp reqid 2 \
mode transport
Error: Mode in optional template not allowed in outbound policy.
Fixes: d1716d5a44c3 ("xfrm: add generic iptfs defines and functionality")
Reported-by: syzbot+0ac4d84afe1066a1f3e9@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6a3ceb94.43b4ff68.30a095.0004.GAE@google.com/T/
Signed-off-by: Antony Antony <antony.antony@secunet.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
net/xfrm/xfrm_user.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 0eb87fc998d1..d6db63304ba6 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2124,13 +2124,12 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family,
switch (ut[i].mode) {
case XFRM_MODE_TUNNEL:
case XFRM_MODE_BEET:
+ case XFRM_MODE_IPTFS:
if (ut[i].optional && dir == XFRM_POLICY_OUT) {
NL_SET_ERR_MSG(extack, "Mode in optional template not allowed in outbound policy");
return -EINVAL;
}
break;
- case XFRM_MODE_IPTFS:
- break;
default:
if (ut[i].family != prev_family) {
NL_SET_ERR_MSG(extack, "Mode in template doesn't support a family change");
--
2.43.0
next prev parent reply other threads:[~2026-07-10 9:04 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 9:03 [PATCH 0/10] pull request (net): ipsec 2026-07-10 Steffen Klassert
2026-07-10 9:03 ` [PATCH 01/10] xfrm: propagate -EINPROGRESS from validate_xmit_xfrm() Steffen Klassert
2026-07-11 11:00 ` patchwork-bot+netdevbpf
2026-07-10 9:03 ` [PATCH 02/10] xfrm: fix stale skb->prev after async crypto steals a GSO segment Steffen Klassert
2026-07-10 9:03 ` [PATCH 03/10] xfrm: nat_keepalive: avoid double free on send error Steffen Klassert
2026-07-10 9:03 ` [PATCH 04/10] xfrm: fix sk_dst_cache double-free in xfrm_user_policy() Steffen Klassert
2026-07-10 9:03 ` [PATCH 05/10] xfrm: cache the offload ifindex for netlink dumps Steffen Klassert
2026-07-10 9:03 ` Steffen Klassert [this message]
2026-07-10 9:03 ` [PATCH 07/10] xfrm: clear mode callbacks after failed mode setup Steffen Klassert
2026-07-10 9:03 ` [PATCH 08/10] xfrm: iptfs: propagate SKBFL_SHARED_FRAG in iptfs_skb_add_frags() Steffen Klassert
2026-07-10 9:03 ` [PATCH 09/10] xfrm6: clear dst.dev on error to avoid double netdev_put in xfrm6_fill_dst() Steffen Klassert
2026-07-10 9:03 ` [PATCH 10/10] xfrm: policy: preallocate inexact bins before xfrm_hash_rebuild reinsert Steffen Klassert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260710090349.343389-7-steffen.klassert@secunet.com \
--to=steffen.klassert@secunet.com \
--cc=davem@davemloft.net \
--cc=herbert@gondor.apana.org.au \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox