Merge pull request #624 from ecsv/batadv-for-18.06
[feed/routing.git] / batman-adv / patches / 0035-batman-adv-Only-read-OGM2-tvlv_len-after-buffer-len-.patch
1 From: Sven Eckelmann <sven@narfation.org>
2 Date: Fri, 23 Aug 2019 14:34:28 +0200
3 Subject: batman-adv: Only read OGM2 tvlv_len after buffer len check
4
5 Multiple batadv_ogm2_packet can be stored in an skbuff. The functions
6 batadv_v_ogm_send_to_if() uses batadv_v_ogm_aggr_packet() to check if there
7 is another additional batadv_ogm2_packet in the skb or not before they
8 continue processing the packet.
9
10 The length for such an OGM2 is BATADV_OGM2_HLEN +
11 batadv_ogm2_packet->tvlv_len. The check must first check that at least
12 BATADV_OGM2_HLEN bytes are available before it accesses tvlv_len (which is
13 part of the header. Otherwise it might try read outside of the currently
14 available skbuff to get the content of tvlv_len.
15
16 Fixes: 667996ebeab4 ("batman-adv: OGMv2 - implement originators logic")
17 Signed-off-by: Sven Eckelmann <sven@narfation.org>
18
19 Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/18f77da3761c5550f42a2d131f0fe5cac62e022d
20
21 diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
22 index 2948b41b06d47c0ee32649fa410b323f39c36151..d241ccc0ca0278173853512c8aa4bfb8b041f996 100644
23 --- a/net/batman-adv/bat_v_ogm.c
24 +++ b/net/batman-adv/bat_v_ogm.c
25 @@ -643,17 +643,23 @@ batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv,
26 * batadv_v_ogm_aggr_packet() - checks if there is another OGM aggregated
27 * @buff_pos: current position in the skb
28 * @packet_len: total length of the skb
29 - * @tvlv_len: tvlv length of the previously considered OGM
30 + * @ogm2_packet: potential OGM2 in buffer
31 *
32 * Return: true if there is enough space for another OGM, false otherwise.
33 */
34 -static bool batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
35 - __be16 tvlv_len)
36 +static bool
37 +batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
38 + const struct batadv_ogm2_packet *ogm2_packet)
39 {
40 int next_buff_pos = 0;
41
42 - next_buff_pos += buff_pos + BATADV_OGM2_HLEN;
43 - next_buff_pos += ntohs(tvlv_len);
44 + /* check if there is enough space for the header */
45 + next_buff_pos += buff_pos + sizeof(*ogm2_packet);
46 + if (next_buff_pos > packet_len)
47 + return false;
48 +
49 + /* check if there is enough space for the optional TVLV */
50 + next_buff_pos += ntohs(ogm2_packet->tvlv_len);
51
52 return (next_buff_pos <= packet_len) &&
53 (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
54 @@ -830,7 +836,7 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb,
55 ogm_packet = (struct batadv_ogm2_packet *)skb->data;
56
57 while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
58 - ogm_packet->tvlv_len)) {
59 + ogm_packet)) {
60 batadv_v_ogm_process(skb, ogm_offset, if_incoming);
61
62 ogm_offset += BATADV_OGM2_HLEN;