batman-adv: Merge bugfixes from 2022.1
[feed/routing.git] / batman-adv / patches / 0011-batman-adv-Don-t-skb_split-skbuffs-with-frag_list.patch
1 From: Sven Eckelmann <sven@narfation.org>
2 Date: Sat, 16 Apr 2022 14:24:34 +0200
3 Subject: batman-adv: Don't skb_split skbuffs with frag_list
4
5 The receiving interface might have used GRO to receive more fragments than
6 MAX_SKB_FRAGS fragments. In this case, these will not be stored in
7 skb_shinfo(skb)->frags but merged into the frag list.
8
9 batman-adv relies on the function skb_split to split packets up into
10 multiple smaller packets which are not larger than the MTU on the outgoing
11 interface. But this function cannot handle frag_list entries and is only
12 operating on skb_shinfo(skb)->frags. If it is still trying to split such an
13 skb and xmit'ing it on an interface without support for NETIF_F_FRAGLIST,
14 then validate_xmit_skb() will try to linearize it. But this fails due to
15 inconsistent information. And __pskb_pull_tail will trigger a BUG_ON after
16 skb_copy_bits() returns an error.
17
18 In case of entries in frag_list, just linearize the skb before operating on
19 it with skb_split().
20
21 Reported-by: Felix Kaechele <felix@kaechele.ca>
22 Tested-by: Felix Kaechele <felix@kaechele.ca>
23 Fixes: 9de347143505 ("batman-adv: layer2 unicast packet fragmentation")
24 Signed-off-by: Sven Eckelmann <sven@narfation.org>
25 Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d467720acaf1b22b0cee58144eeaf9ef6c5e285c
26
27 --- a/net/batman-adv/fragmentation.c
28 +++ b/net/batman-adv/fragmentation.c
29 @@ -475,6 +475,17 @@ int batadv_frag_send_packet(struct sk_bu
30 goto free_skb;
31 }
32
33 + /* GRO might have added fragments to the fragment list instead of
34 + * frags[]. But this is not handled by skb_split and must be
35 + * linearized to avoid incorrect length information after all
36 + * batman-adv fragments were created and submitted to the
37 + * hard-interface
38 + */
39 + if (skb_has_frag_list(skb) && __skb_linearize(skb)) {
40 + ret = -ENOMEM;
41 + goto free_skb;
42 + }
43 +
44 /* Create one header to be copied to all fragments */
45 frag_header.packet_type = BATADV_UNICAST_FRAG;
46 frag_header.version = BATADV_COMPAT_VERSION;