Commit f46373e0 authored by Florian Westphal's avatar Florian Westphal Committed by Greg Kroah-Hartman

xfrm: refine validation of template and selector families

commit 35e61038 upstream.

The check assumes that in transport mode, the first templates family
must match the address family of the policy selector.

Syzkaller managed to build a template using MODE_ROUTEOPTIMIZATION,
with ipv4-in-ipv6 chain, leading to following splat:

BUG: KASAN: stack-out-of-bounds in xfrm_state_find+0x1db/0x1854
Read of size 4 at addr ffff888063e57aa0 by task a.out/2050
 xfrm_resolve_and_create_bundle+0x108/0x1000 [..]

Problem is that addresses point into flowi4 struct, but xfrm_state_find
treats them as being ipv6 because it uses templ->encap_family is used
(AF_INET6 in case of reproducer) rather than family (AF_INET).

This patch inverts the logic: Enforce 'template family must match
selector' EXCEPT for tunnel and BEET mode.

In BEET and Tunnel mode, xfrm_tmpl_resolve_one will have remote/local
address pointers changed to point at the addresses found in the template,
rather than the flowi ones, so no oob read will occur.

Reported-by: default avatarDaniel Borkmann <>
Signed-off-by: default avatarFlorian Westphal <>
Signed-off-by: default avatarSteffen Klassert <>
Signed-off-by: default avatarGreg Kroah-Hartman <>
parent df985724
......@@ -1488,10 +1488,15 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
if (!ut[i].family)
ut[i].family = family;
if ((ut[i].mode == XFRM_MODE_TRANSPORT) &&
(ut[i].family != prev_family))
return -EINVAL;
switch (ut[i].mode) {
if (ut[i].family != prev_family)
return -EINVAL;
if (ut[i].mode >= XFRM_MODE_MAX)
return -EINVAL;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment