batman-adv: Merge bugfixes from 2018.4
[feed/routing.git] / batman-adv / patches / 0023-batman-adv-Expand-merged-fragment-buffer-for-full-pa.patch
1 From: Sven Eckelmann <sven@narfation.org>
2 Date: Wed, 7 Nov 2018 23:09:12 +0100
3 Subject: [PATCH] batman-adv: Expand merged fragment buffer for full packet
4
5 The complete size ("total_size") of the fragmented packet is stored in the
6 fragment header and in the size of the fragment chain. When the fragments
7 are ready for merge, the skbuff's tail of the first fragment is expanded to
8 have enough room after the data pointer for at least total_size. This means
9 that it gets expanded by total_size - first_skb->len.
10
11 But this is ignoring the fact that after expanding the buffer, the fragment
12 header is pulled by from this buffer. Assuming that the tailroom of the
13 buffer was already 0, the buffer after the data pointer of the skbuff is
14 now only total_size - len(fragment_header) large. When the merge function
15 is then processing the remaining fragments, the code to copy the data over
16 to the merged skbuff will cause an skb_over_panic when it tries to actually
17 put enough data to fill the total_size bytes of the packet.
18
19 The size of the skb_pull must therefore also be taken into account when the
20 buffer's tailroom is expanded.
21
22 Fixes: 9b3eab61754d ("batman-adv: Receive fragmented packets and merge")
23 Reported-by: Martin Weinelt <martin@darmstadt.freifunk.net>
24 Co-authored-by: Linus Lüssing <linus.luessing@c0d3.blue>
25 Signed-off-by: Sven Eckelmann <sven@narfation.org>
26
27 Origin: other, https://patchwork.open-mesh.org/patch/17616/
28 ---
29 net/batman-adv/fragmentation.c | 2 +-
30 1 file changed, 1 insertion(+), 1 deletion(-)
31
32 diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
33 index 0fddc17106bd8a0e3f064fee9adba7c226f34682..5b71a289d04fc80de6c20e7a24d621727c77825a 100644
34 --- a/net/batman-adv/fragmentation.c
35 +++ b/net/batman-adv/fragmentation.c
36 @@ -275,7 +275,7 @@ batadv_frag_merge_packets(struct hlist_head *chain)
37 kfree(entry);
38
39 packet = (struct batadv_frag_packet *)skb_out->data;
40 - size = ntohs(packet->total_size);
41 + size = ntohs(packet->total_size) + hdr_size;
42
43 /* Make room for the rest of the fragments. */
44 if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) {