]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.19.22/xfrm-refine-validation-of-template-and-selector-families.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.19.22 / xfrm-refine-validation-of-template-and-selector-families.patch
1 From 35e6103861a3a970de6c84688c6e7a1f65b164ca Mon Sep 17 00:00:00 2001
2 From: Florian Westphal <fw@strlen.de>
3 Date: Wed, 9 Jan 2019 14:37:34 +0100
4 Subject: xfrm: refine validation of template and selector families
5
6 From: Florian Westphal <fw@strlen.de>
7
8 commit 35e6103861a3a970de6c84688c6e7a1f65b164ca upstream.
9
10 The check assumes that in transport mode, the first templates family
11 must match the address family of the policy selector.
12
13 Syzkaller managed to build a template using MODE_ROUTEOPTIMIZATION,
14 with ipv4-in-ipv6 chain, leading to following splat:
15
16 BUG: KASAN: stack-out-of-bounds in xfrm_state_find+0x1db/0x1854
17 Read of size 4 at addr ffff888063e57aa0 by task a.out/2050
18 xfrm_state_find+0x1db/0x1854
19 xfrm_tmpl_resolve+0x100/0x1d0
20 xfrm_resolve_and_create_bundle+0x108/0x1000 [..]
21
22 Problem is that addresses point into flowi4 struct, but xfrm_state_find
23 treats them as being ipv6 because it uses templ->encap_family is used
24 (AF_INET6 in case of reproducer) rather than family (AF_INET).
25
26 This patch inverts the logic: Enforce 'template family must match
27 selector' EXCEPT for tunnel and BEET mode.
28
29 In BEET and Tunnel mode, xfrm_tmpl_resolve_one will have remote/local
30 address pointers changed to point at the addresses found in the template,
31 rather than the flowi ones, so no oob read will occur.
32
33 Reported-by: 3ntr0py1337@gmail.com
34 Reported-by: Daniel Borkmann <daniel@iogearbox.net>
35 Signed-off-by: Florian Westphal <fw@strlen.de>
36 Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
37 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
38
39 ---
40 net/xfrm/xfrm_user.c | 13 +++++++++----
41 1 file changed, 9 insertions(+), 4 deletions(-)
42
43 --- a/net/xfrm/xfrm_user.c
44 +++ b/net/xfrm/xfrm_user.c
45 @@ -1488,10 +1488,15 @@ static int validate_tmpl(int nr, struct
46 if (!ut[i].family)
47 ut[i].family = family;
48
49 - if ((ut[i].mode == XFRM_MODE_TRANSPORT) &&
50 - (ut[i].family != prev_family))
51 - return -EINVAL;
52 -
53 + switch (ut[i].mode) {
54 + case XFRM_MODE_TUNNEL:
55 + case XFRM_MODE_BEET:
56 + break;
57 + default:
58 + if (ut[i].family != prev_family)
59 + return -EINVAL;
60 + break;
61 + }
62 if (ut[i].mode >= XFRM_MODE_MAX)
63 return -EINVAL;
64