]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-6.6/ipv6-fix-infinite-recursion-in-fib6_dump_done.patch
780311e6e023fe58c601c907aa45ba28a7189df1
[thirdparty/kernel/stable-queue.git] / queue-6.6 / ipv6-fix-infinite-recursion-in-fib6_dump_done.patch
1 From d21d40605bca7bd5fc23ef03d4c1ca1f48bc2cae Mon Sep 17 00:00:00 2001
2 From: Kuniyuki Iwashima <kuniyu@amazon.com>
3 Date: Mon, 1 Apr 2024 14:10:04 -0700
4 Subject: ipv6: Fix infinite recursion in fib6_dump_done().
5
6 From: Kuniyuki Iwashima <kuniyu@amazon.com>
7
8 commit d21d40605bca7bd5fc23ef03d4c1ca1f48bc2cae upstream.
9
10 syzkaller reported infinite recursive calls of fib6_dump_done() during
11 netlink socket destruction. [1]
12
13 From the log, syzkaller sent an AF_UNSPEC RTM_GETROUTE message, and then
14 the response was generated. The following recvmmsg() resumed the dump
15 for IPv6, but the first call of inet6_dump_fib() failed at kzalloc() due
16 to the fault injection. [0]
17
18 12:01:34 executing program 3:
19 r0 = socket$nl_route(0x10, 0x3, 0x0)
20 sendmsg$nl_route(r0, ... snip ...)
21 recvmmsg(r0, ... snip ...) (fail_nth: 8)
22
23 Here, fib6_dump_done() was set to nlk_sk(sk)->cb.done, and the next call
24 of inet6_dump_fib() set it to nlk_sk(sk)->cb.args[3]. syzkaller stopped
25 receiving the response halfway through, and finally netlink_sock_destruct()
26 called nlk_sk(sk)->cb.done().
27
28 fib6_dump_done() calls fib6_dump_end() and nlk_sk(sk)->cb.done() if it
29 is still not NULL. fib6_dump_end() rewrites nlk_sk(sk)->cb.done() by
30 nlk_sk(sk)->cb.args[3], but it has the same function, not NULL, calling
31 itself recursively and hitting the stack guard page.
32
33 To avoid the issue, let's set the destructor after kzalloc().
34
35 [0]:
36 FAULT_INJECTION: forcing a failure.
37 name failslab, interval 1, probability 0, space 0, times 0
38 CPU: 1 PID: 432110 Comm: syz-executor.3 Not tainted 6.8.0-12821-g537c2e91d354-dirty #11
39 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
40 Call Trace:
41 <TASK>
42 dump_stack_lvl (lib/dump_stack.c:117)
43 should_fail_ex (lib/fault-inject.c:52 lib/fault-inject.c:153)
44 should_failslab (mm/slub.c:3733)
45 kmalloc_trace (mm/slub.c:3748 mm/slub.c:3827 mm/slub.c:3992)
46 inet6_dump_fib (./include/linux/slab.h:628 ./include/linux/slab.h:749 net/ipv6/ip6_fib.c:662)
47 rtnl_dump_all (net/core/rtnetlink.c:4029)
48 netlink_dump (net/netlink/af_netlink.c:2269)
49 netlink_recvmsg (net/netlink/af_netlink.c:1988)
50 ____sys_recvmsg (net/socket.c:1046 net/socket.c:2801)
51 ___sys_recvmsg (net/socket.c:2846)
52 do_recvmmsg (net/socket.c:2943)
53 __x64_sys_recvmmsg (net/socket.c:3041 net/socket.c:3034 net/socket.c:3034)
54
55 [1]:
56 BUG: TASK stack guard page was hit at 00000000f2fa9af1 (stack is 00000000b7912430..000000009a436beb)
57 stack guard page: 0000 [#1] PREEMPT SMP KASAN
58 CPU: 1 PID: 223719 Comm: kworker/1:3 Not tainted 6.8.0-12821-g537c2e91d354-dirty #11
59 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
60 Workqueue: events netlink_sock_destruct_work
61 RIP: 0010:fib6_dump_done (net/ipv6/ip6_fib.c:570)
62 Code: 3c 24 e8 f3 e9 51 fd e9 28 fd ff ff 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 f3 0f 1e fa 41 57 41 56 41 55 41 54 55 48 89 fd <53> 48 8d 5d 60 e8 b6 4d 07 fd 48 89 da 48 b8 00 00 00 00 00 fc ff
63 RSP: 0018:ffffc9000d980000 EFLAGS: 00010293
64 RAX: 0000000000000000 RBX: ffffffff84405990 RCX: ffffffff844059d3
65 RDX: ffff8881028e0000 RSI: ffffffff84405ac2 RDI: ffff88810c02f358
66 RBP: ffff88810c02f358 R08: 0000000000000007 R09: 0000000000000000
67 R10: 0000000000000000 R11: 0000000000000224 R12: 0000000000000000
68 R13: ffff888007c82c78 R14: ffff888007c82c68 R15: ffff888007c82c68
69 FS: 0000000000000000(0000) GS:ffff88811b100000(0000) knlGS:0000000000000000
70 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
71 CR2: ffffc9000d97fff8 CR3: 0000000102309002 CR4: 0000000000770ef0
72 PKRU: 55555554
73 Call Trace:
74 <#DF>
75 </#DF>
76 <TASK>
77 fib6_dump_done (net/ipv6/ip6_fib.c:572 (discriminator 1))
78 fib6_dump_done (net/ipv6/ip6_fib.c:572 (discriminator 1))
79 ...
80 fib6_dump_done (net/ipv6/ip6_fib.c:572 (discriminator 1))
81 fib6_dump_done (net/ipv6/ip6_fib.c:572 (discriminator 1))
82 netlink_sock_destruct (net/netlink/af_netlink.c:401)
83 __sk_destruct (net/core/sock.c:2177 (discriminator 2))
84 sk_destruct (net/core/sock.c:2224)
85 __sk_free (net/core/sock.c:2235)
86 sk_free (net/core/sock.c:2246)
87 process_one_work (kernel/workqueue.c:3259)
88 worker_thread (kernel/workqueue.c:3329 kernel/workqueue.c:3416)
89 kthread (kernel/kthread.c:388)
90 ret_from_fork (arch/x86/kernel/process.c:153)
91 ret_from_fork_asm (arch/x86/entry/entry_64.S:256)
92 Modules linked in:
93
94 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
95 Reported-by: syzkaller <syzkaller@googlegroups.com>
96 Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
97 Reviewed-by: Eric Dumazet <edumazet@google.com>
98 Reviewed-by: David Ahern <dsahern@kernel.org>
99 Link: https://lore.kernel.org/r/20240401211003.25274-1-kuniyu@amazon.com
100 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
101 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
102 ---
103 net/ipv6/ip6_fib.c | 14 +++++++-------
104 1 file changed, 7 insertions(+), 7 deletions(-)
105
106 --- a/net/ipv6/ip6_fib.c
107 +++ b/net/ipv6/ip6_fib.c
108 @@ -645,19 +645,19 @@ static int inet6_dump_fib(struct sk_buff
109 if (!w) {
110 /* New dump:
111 *
112 - * 1. hook callback destructor.
113 - */
114 - cb->args[3] = (long)cb->done;
115 - cb->done = fib6_dump_done;
116 -
117 - /*
118 - * 2. allocate and initialize walker.
119 + * 1. allocate and initialize walker.
120 */
121 w = kzalloc(sizeof(*w), GFP_ATOMIC);
122 if (!w)
123 return -ENOMEM;
124 w->func = fib6_dump_node;
125 cb->args[2] = (long)w;
126 +
127 + /* 2. hook callback destructor.
128 + */
129 + cb->args[3] = (long)cb->done;
130 + cb->done = fib6_dump_done;
131 +
132 }
133
134 arg.skb = skb;