diff options
author | David S. Miller <davem@davemloft.net> | 2019-08-31 16:16:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-08-31 16:16:07 -0400 |
commit | 5b161002bd6d8b3ee4553a697524e61c3b92769c (patch) | |
tree | 87e59eb784f9078691b7e853c63e2c90af6ed2c8 | |
parent | c3d7a089f945124770748b4eb7d5e2d1b40dadf9 (diff) | |
parent | 0ff0f15a32c093381ad1abc06abe85afb561ab28 (diff) |
Merge tag 'batadv-net-for-davem-20190830' of git://git.open-mesh.org/linux-merge
Simon Wunderlich says:
====================
Here are two batman-adv bugfixes:
- Fix OGM and OGMv2 header read boundary check,
by Sven Eckelmann (2 patches)
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/batman-adv/bat_iv_ogm.c | 20 | ||||
-rw-r--r-- | net/batman-adv/bat_v_ogm.c | 18 |
2 files changed, 25 insertions, 13 deletions
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 240ed70912d6..d78938e3e008 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -277,17 +277,23 @@ static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv) | |||
277 | * batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached | 277 | * batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached |
278 | * @buff_pos: current position in the skb | 278 | * @buff_pos: current position in the skb |
279 | * @packet_len: total length of the skb | 279 | * @packet_len: total length of the skb |
280 | * @tvlv_len: tvlv length of the previously considered OGM | 280 | * @ogm_packet: potential OGM in buffer |
281 | * | 281 | * |
282 | * Return: true if there is enough space for another OGM, false otherwise. | 282 | * Return: true if there is enough space for another OGM, false otherwise. |
283 | */ | 283 | */ |
284 | static bool batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len, | 284 | static bool |
285 | __be16 tvlv_len) | 285 | batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len, |
286 | const struct batadv_ogm_packet *ogm_packet) | ||
286 | { | 287 | { |
287 | int next_buff_pos = 0; | 288 | int next_buff_pos = 0; |
288 | 289 | ||
289 | next_buff_pos += buff_pos + BATADV_OGM_HLEN; | 290 | /* check if there is enough space for the header */ |
290 | next_buff_pos += ntohs(tvlv_len); | 291 | next_buff_pos += buff_pos + sizeof(*ogm_packet); |
292 | if (next_buff_pos > packet_len) | ||
293 | return false; | ||
294 | |||
295 | /* check if there is enough space for the optional TVLV */ | ||
296 | next_buff_pos += ntohs(ogm_packet->tvlv_len); | ||
291 | 297 | ||
292 | return (next_buff_pos <= packet_len) && | 298 | return (next_buff_pos <= packet_len) && |
293 | (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES); | 299 | (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES); |
@@ -315,7 +321,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet, | |||
315 | 321 | ||
316 | /* adjust all flags and log packets */ | 322 | /* adjust all flags and log packets */ |
317 | while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, | 323 | while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len, |
318 | batadv_ogm_packet->tvlv_len)) { | 324 | batadv_ogm_packet)) { |
319 | /* we might have aggregated direct link packets with an | 325 | /* we might have aggregated direct link packets with an |
320 | * ordinary base packet | 326 | * ordinary base packet |
321 | */ | 327 | */ |
@@ -1704,7 +1710,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, | |||
1704 | 1710 | ||
1705 | /* unpack the aggregated packets and process them one by one */ | 1711 | /* unpack the aggregated packets and process them one by one */ |
1706 | while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb), | 1712 | while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb), |
1707 | ogm_packet->tvlv_len)) { | 1713 | ogm_packet)) { |
1708 | batadv_iv_ogm_process(skb, ogm_offset, if_incoming); | 1714 | batadv_iv_ogm_process(skb, ogm_offset, if_incoming); |
1709 | 1715 | ||
1710 | ogm_offset += BATADV_OGM_HLEN; | 1716 | ogm_offset += BATADV_OGM_HLEN; |
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c index fad95ef64e01..bc06e3cdfa84 100644 --- a/net/batman-adv/bat_v_ogm.c +++ b/net/batman-adv/bat_v_ogm.c | |||
@@ -631,17 +631,23 @@ batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv, | |||
631 | * batadv_v_ogm_aggr_packet() - checks if there is another OGM aggregated | 631 | * batadv_v_ogm_aggr_packet() - checks if there is another OGM aggregated |
632 | * @buff_pos: current position in the skb | 632 | * @buff_pos: current position in the skb |
633 | * @packet_len: total length of the skb | 633 | * @packet_len: total length of the skb |
634 | * @tvlv_len: tvlv length of the previously considered OGM | 634 | * @ogm2_packet: potential OGM2 in buffer |
635 | * | 635 | * |
636 | * Return: true if there is enough space for another OGM, false otherwise. | 636 | * Return: true if there is enough space for another OGM, false otherwise. |
637 | */ | 637 | */ |
638 | static bool batadv_v_ogm_aggr_packet(int buff_pos, int packet_len, | 638 | static bool |
639 | __be16 tvlv_len) | 639 | batadv_v_ogm_aggr_packet(int buff_pos, int packet_len, |
640 | const struct batadv_ogm2_packet *ogm2_packet) | ||
640 | { | 641 | { |
641 | int next_buff_pos = 0; | 642 | int next_buff_pos = 0; |
642 | 643 | ||
643 | next_buff_pos += buff_pos + BATADV_OGM2_HLEN; | 644 | /* check if there is enough space for the header */ |
644 | next_buff_pos += ntohs(tvlv_len); | 645 | next_buff_pos += buff_pos + sizeof(*ogm2_packet); |
646 | if (next_buff_pos > packet_len) | ||
647 | return false; | ||
648 | |||
649 | /* check if there is enough space for the optional TVLV */ | ||
650 | next_buff_pos += ntohs(ogm2_packet->tvlv_len); | ||
645 | 651 | ||
646 | return (next_buff_pos <= packet_len) && | 652 | return (next_buff_pos <= packet_len) && |
647 | (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES); | 653 | (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES); |
@@ -818,7 +824,7 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb, | |||
818 | ogm_packet = (struct batadv_ogm2_packet *)skb->data; | 824 | ogm_packet = (struct batadv_ogm2_packet *)skb->data; |
819 | 825 | ||
820 | while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb), | 826 | while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb), |
821 | ogm_packet->tvlv_len)) { | 827 | ogm_packet)) { |
822 | batadv_v_ogm_process(skb, ogm_offset, if_incoming); | 828 | batadv_v_ogm_process(skb, ogm_offset, if_incoming); |
823 | 829 | ||
824 | ogm_offset += BATADV_OGM2_HLEN; | 830 | ogm_offset += BATADV_OGM2_HLEN; |