Skip to content

Commit a15d56a

Browse files
ecsvsimonwunderlich
authored andcommitted
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: ef26157 ("batman-adv: tvlv - basic infrastructure") Reported-by: [email protected] Signed-off-by: Sven Eckelmann <[email protected]> Acked-by: Antonio Quartulli <[email protected]> Signed-off-by: Simon Wunderlich <[email protected]>
1 parent 3ee1bb7 commit a15d56a

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

net/batman-adv/bat_iv_ogm.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -277,17 +277,23 @@ static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv)
277277
* batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached
278278
* @buff_pos: current position in the skb
279279
* @packet_len: total length of the skb
280-
* @tvlv_len: tvlv length of the previously considered OGM
280+
* @ogm_packet: potential OGM in buffer
281281
*
282282
* Return: true if there is enough space for another OGM, false otherwise.
283283
*/
284-
static bool batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
285-
__be16 tvlv_len)
284+
static bool
285+
batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
286+
const struct batadv_ogm_packet *ogm_packet)
286287
{
287288
int next_buff_pos = 0;
288289

289-
next_buff_pos += buff_pos + BATADV_OGM_HLEN;
290-
next_buff_pos += ntohs(tvlv_len);
290+
/* check if there is enough space for the header */
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);
291297

292298
return (next_buff_pos <= packet_len) &&
293299
(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,
315321

316322
/* adjust all flags and log packets */
317323
while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
318-
batadv_ogm_packet->tvlv_len)) {
324+
batadv_ogm_packet)) {
319325
/* we might have aggregated direct link packets with an
320326
* ordinary base packet
321327
*/
@@ -1704,7 +1710,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
17041710

17051711
/* unpack the aggregated packets and process them one by one */
17061712
while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
1707-
ogm_packet->tvlv_len)) {
1713+
ogm_packet)) {
17081714
batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
17091715

17101716
ogm_offset += BATADV_OGM_HLEN;

0 commit comments

Comments
 (0)