Merge pull request #624 from ecsv/batadv-for-18.06
[feed/routing.git] / batman-adv / patches / 0034-batman-adv-Only-read-OGM-tvlv_len-after-buffer-len-c.patch
1 From: Sven Eckelmann <sven@narfation.org>
2 Date: Fri, 23 Aug 2019 14:34:27 +0200
3 Subject: batman-adv: Only read OGM tvlv_len after buffer len check
4
5 Multiple batadv_ogm_packet can be stored in an skbuff. The functions
6 batadv_iv_ogm_send_to_if()/batadv_iv_ogm_receive() use
7 batadv_iv_ogm_aggr_packet() to check if there is another additional
8 batadv_ogm_packet in the skb or not before they continue processing the
9 packet.
10
11 The length for such an OGM is BATADV_OGM_HLEN +
12 batadv_ogm_packet->tvlv_len. The check must first check that at least
13 BATADV_OGM_HLEN bytes are available before it accesses tvlv_len (which is
14 part of the header. Otherwise it might try read outside of the currently
15 available skbuff to get the content of tvlv_len.
16
17 Fixes: 0b6aa0d43767 ("batman-adv: tvlv - basic infrastructure")
18 Reported-by: syzbot+355cab184197dbbfa384@syzkaller.appspotmail.com
19 Signed-off-by: Sven Eckelmann <sven@narfation.org>
20 Acked-by: Antonio Quartulli <a@unstable.cc>
21
22 Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/07b6051ebcfaa7ea89b4f278eca2ff4070d29e56
23
24 diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
25 index 0b7b36fa0d5cd440ddef141ad27acfe7b20aee43..36f244125d24c800d35249af7639d39a516588d4 100644
26 --- a/net/batman-adv/bat_iv_ogm.c
27 +++ b/net/batman-adv/bat_iv_ogm.c
28 @@ -463,17 +463,23 @@ static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv)
29 * batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached
30 * @buff_pos: current position in the skb
31 * @packet_len: total length of the skb
32 - * @tvlv_len: tvlv length of the previously considered OGM
33 + * @ogm_packet: potential OGM in buffer
34 *
35 * Return: true if there is enough space for another OGM, false otherwise.
36 */
37 -static bool batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
38 - __be16 tvlv_len)
39 +static bool
40 +batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
41 + const struct batadv_ogm_packet *ogm_packet)
42 {
43 int next_buff_pos = 0;
44
45 - next_buff_pos += buff_pos + BATADV_OGM_HLEN;
46 - next_buff_pos += ntohs(tvlv_len);
47 + /* check if there is enough space for the header */
48 + next_buff_pos += buff_pos + sizeof(*ogm_packet);
49 + if (next_buff_pos > packet_len)
50 + return false;
51 +
52 + /* check if there is enough space for the optional TVLV */
53 + next_buff_pos += ntohs(ogm_packet->tvlv_len);
54
55 return (next_buff_pos <= packet_len) &&
56 (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
57 @@ -501,7 +507,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
58
59 /* adjust all flags and log packets */
60 while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
61 - batadv_ogm_packet->tvlv_len)) {
62 + batadv_ogm_packet)) {
63 /* we might have aggregated direct link packets with an
64 * ordinary base packet
65 */
66 @@ -1852,7 +1858,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
67
68 /* unpack the aggregated packets and process them one by one */
69 while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
70 - ogm_packet->tvlv_len)) {
71 + ogm_packet)) {
72 batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
73
74 ogm_offset += BATADV_OGM_HLEN;