]>
Commit | Line | Data |
---|---|---|
201b1fbe GKH |
1 | From foo@baz Thu Mar 29 08:33:08 CEST 2018 |
2 | From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> | |
3 | Date: Thu, 8 Mar 2018 17:00:02 +0100 | |
4 | Subject: ipv6: fix access to non-linear packet in ndisc_fill_redirect_hdr_option() | |
5 | ||
6 | From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> | |
7 | ||
8 | ||
9 | [ Upstream commit 9f62c15f28b0d1d746734666d88a79f08ba1e43e ] | |
10 | ||
11 | Fix the following slab-out-of-bounds kasan report in | |
12 | ndisc_fill_redirect_hdr_option when the incoming ipv6 packet is not | |
13 | linear and the accessed data are not in the linear data region of orig_skb. | |
14 | ||
15 | [ 1503.122508] ================================================================== | |
16 | [ 1503.122832] BUG: KASAN: slab-out-of-bounds in ndisc_send_redirect+0x94e/0x990 | |
17 | [ 1503.123036] Read of size 1184 at addr ffff8800298ab6b0 by task netperf/1932 | |
18 | ||
19 | [ 1503.123220] CPU: 0 PID: 1932 Comm: netperf Not tainted 4.16.0-rc2+ #124 | |
20 | [ 1503.123347] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.10.2-2.fc27 04/01/2014 | |
21 | [ 1503.123527] Call Trace: | |
22 | [ 1503.123579] <IRQ> | |
23 | [ 1503.123638] print_address_description+0x6e/0x280 | |
24 | [ 1503.123849] kasan_report+0x233/0x350 | |
25 | [ 1503.123946] memcpy+0x1f/0x50 | |
26 | [ 1503.124037] ndisc_send_redirect+0x94e/0x990 | |
27 | [ 1503.125150] ip6_forward+0x1242/0x13b0 | |
28 | [...] | |
29 | [ 1503.153890] Allocated by task 1932: | |
30 | [ 1503.153982] kasan_kmalloc+0x9f/0xd0 | |
31 | [ 1503.154074] __kmalloc_track_caller+0xb5/0x160 | |
32 | [ 1503.154198] __kmalloc_reserve.isra.41+0x24/0x70 | |
33 | [ 1503.154324] __alloc_skb+0x130/0x3e0 | |
34 | [ 1503.154415] sctp_packet_transmit+0x21a/0x1810 | |
35 | [ 1503.154533] sctp_outq_flush+0xc14/0x1db0 | |
36 | [ 1503.154624] sctp_do_sm+0x34e/0x2740 | |
37 | [ 1503.154715] sctp_primitive_SEND+0x57/0x70 | |
38 | [ 1503.154807] sctp_sendmsg+0xaa6/0x1b10 | |
39 | [ 1503.154897] sock_sendmsg+0x68/0x80 | |
40 | [ 1503.154987] ___sys_sendmsg+0x431/0x4b0 | |
41 | [ 1503.155078] __sys_sendmsg+0xa4/0x130 | |
42 | [ 1503.155168] do_syscall_64+0x171/0x3f0 | |
43 | [ 1503.155259] entry_SYSCALL_64_after_hwframe+0x42/0xb7 | |
44 | ||
45 | [ 1503.155436] Freed by task 1932: | |
46 | [ 1503.155527] __kasan_slab_free+0x134/0x180 | |
47 | [ 1503.155618] kfree+0xbc/0x180 | |
48 | [ 1503.155709] skb_release_data+0x27f/0x2c0 | |
49 | [ 1503.155800] consume_skb+0x94/0xe0 | |
50 | [ 1503.155889] sctp_chunk_put+0x1aa/0x1f0 | |
51 | [ 1503.155979] sctp_inq_pop+0x2f8/0x6e0 | |
52 | [ 1503.156070] sctp_assoc_bh_rcv+0x6a/0x230 | |
53 | [ 1503.156164] sctp_inq_push+0x117/0x150 | |
54 | [ 1503.156255] sctp_backlog_rcv+0xdf/0x4a0 | |
55 | [ 1503.156346] __release_sock+0x142/0x250 | |
56 | [ 1503.156436] release_sock+0x80/0x180 | |
57 | [ 1503.156526] sctp_sendmsg+0xbb0/0x1b10 | |
58 | [ 1503.156617] sock_sendmsg+0x68/0x80 | |
59 | [ 1503.156708] ___sys_sendmsg+0x431/0x4b0 | |
60 | [ 1503.156799] __sys_sendmsg+0xa4/0x130 | |
61 | [ 1503.156889] do_syscall_64+0x171/0x3f0 | |
62 | [ 1503.156980] entry_SYSCALL_64_after_hwframe+0x42/0xb7 | |
63 | ||
64 | [ 1503.157158] The buggy address belongs to the object at ffff8800298ab600 | |
65 | which belongs to the cache kmalloc-1024 of size 1024 | |
66 | [ 1503.157444] The buggy address is located 176 bytes inside of | |
67 | 1024-byte region [ffff8800298ab600, ffff8800298aba00) | |
68 | [ 1503.157702] The buggy address belongs to the page: | |
69 | [ 1503.157820] page:ffffea0000a62a00 count:1 mapcount:0 mapping:0000000000000000 index:0x0 compound_mapcount: 0 | |
70 | [ 1503.158053] flags: 0x4000000000008100(slab|head) | |
71 | [ 1503.158171] raw: 4000000000008100 0000000000000000 0000000000000000 00000001800e000e | |
72 | [ 1503.158350] raw: dead000000000100 dead000000000200 ffff880036002600 0000000000000000 | |
73 | [ 1503.158523] page dumped because: kasan: bad access detected | |
74 | ||
75 | [ 1503.158698] Memory state around the buggy address: | |
76 | [ 1503.158816] ffff8800298ab900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
77 | [ 1503.158988] ffff8800298ab980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
78 | [ 1503.159165] >ffff8800298aba00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc | |
79 | [ 1503.159338] ^ | |
80 | [ 1503.159436] ffff8800298aba80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb | |
81 | [ 1503.159610] ffff8800298abb00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb | |
82 | [ 1503.159785] ================================================================== | |
83 | [ 1503.159964] Disabling lock debugging due to kernel taint | |
84 | ||
85 | The test scenario to trigger the issue consists of 4 devices: | |
86 | - H0: data sender, connected to LAN0 | |
87 | - H1: data receiver, connected to LAN1 | |
88 | - GW0 and GW1: routers between LAN0 and LAN1. Both of them have an | |
89 | ethernet connection on LAN0 and LAN1 | |
90 | On H{0,1} set GW0 as default gateway while on GW0 set GW1 as next hop for | |
91 | data from LAN0 to LAN1. | |
92 | Moreover create an ip6ip6 tunnel between H0 and H1 and send 3 concurrent | |
93 | data streams (TCP/UDP/SCTP) from H0 to H1 through ip6ip6 tunnel (send | |
94 | buffer size is set to 16K). While data streams are active flush the route | |
95 | cache on HA multiple times. | |
96 | I have not been able to identify a given commit that introduced the issue | |
97 | since, using the reproducer described above, the kasan report has been | |
98 | triggered from 4.14 and I have not gone back further. | |
99 | ||
100 | Reported-by: Jianlin Shi <jishi@redhat.com> | |
101 | Reviewed-by: Stefano Brivio <sbrivio@redhat.com> | |
102 | Reviewed-by: Eric Dumazet <edumazet@google.com> | |
103 | Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> | |
104 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
105 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
106 | --- | |
107 | net/ipv6/ndisc.c | 3 ++- | |
108 | 1 file changed, 2 insertions(+), 1 deletion(-) | |
109 | ||
110 | --- a/net/ipv6/ndisc.c | |
111 | +++ b/net/ipv6/ndisc.c | |
112 | @@ -1478,7 +1478,8 @@ static void ndisc_fill_redirect_hdr_opti | |
113 | *(opt++) = (rd_len >> 3); | |
114 | opt += 6; | |
115 | ||
116 | - memcpy(opt, ipv6_hdr(orig_skb), rd_len - 8); | |
117 | + skb_copy_bits(orig_skb, skb_network_offset(orig_skb), opt, | |
118 | + rd_len - 8); | |
119 | } | |
120 | ||
121 | void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) |