aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Eckelmann <sven@narfation.org>2019-08-22 02:55:36 -0400
committerSimon Wunderlich <sw@simonwunderlich.de>2019-08-23 12:20:17 -0400
commita15d56a60760aa9dbe26343b9a0ac5228f35d445 (patch)
tree1db1303a1b1511df243c7f0dd4a0f8a4e3ec245a
parent3ee1bb7aae97324ec9078da1f00cb2176919563f (diff)
batman-adv: Only read OGM tvlv_len after buffer len check
Multiple batadv_ogm_packet can be stored in an skbuff. The functions batadv_iv_ogm_send_to_if()/batadv_iv_ogm_receive() use batadv_iv_ogm_aggr_packet() to check if there is another additional batadv_ogm_packet in the skb or not before they continue processing the packet. The length for such an OGM is BATADV_OGM_HLEN + batadv_ogm_packet->tvlv_len. The check must first check that at least BATADV_OGM_HLEN bytes are available before it accesses tvlv_len (which is part of the header. Otherwise it might try read outside of the currently available skbuff to get the content of tvlv_len. Fixes: ef26157747d4 ("batman-adv: tvlv - basic infrastructure") Reported-by: syzbot+355cab184197dbbfa384@syzkaller.appspotmail.com Signed-off-by: Sven Eckelmann <sven@narfation.org> Acked-by: Antonio Quartulli <a@unstable.cc> Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
-rw-r--r--net/batman-adv/bat_iv_ogm.c20
1 files changed, 13 insertions, 7 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 */
284static bool batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len, 284static bool
285 __be16 tvlv_len) 285batadv_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;