mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
batman-adv: dat: ensure accessible eth_hdr proto field
When batadv_get_vid() accesses the proto field of the ethernet header, it
is not checking if the data itself is accessible. The caller is responsible
for it. But in contrast to other call sites, batadv_dat_get_vid() and its
caller didn't make sure this is true. This could have caused an
out-of-bounds access.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Fixes: be1db4f661 ("batman-adv: make the Distributed ARP Table vlan aware")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
This commit is contained in:
parent
cdf3b5af2b
commit
26560c4a03
|
|
@ -1066,6 +1066,9 @@ static u16 batadv_arp_get_type(struct batadv_priv *bat_priv,
|
|||
* @skb: the buffer containing the packet to extract the VID from
|
||||
* @hdr_size: the size of the batman-adv header encapsulating the packet
|
||||
*
|
||||
* The caller must ensure that at least @hdr_size + ETH_HLEN bytes are
|
||||
* accessible after skb->data.
|
||||
*
|
||||
* Return: If the packet embedded in the skb is vlan tagged this function
|
||||
* returns the VID with the BATADV_VLAN_HAS_TAG flag. Otherwise BATADV_NO_FLAGS
|
||||
* is returned.
|
||||
|
|
@ -1148,6 +1151,10 @@ bool batadv_dat_snoop_outgoing_arp_request(struct batadv_priv *bat_priv,
|
|||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
goto out;
|
||||
|
||||
/* first, find out the vid. */
|
||||
if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
|
||||
goto out;
|
||||
|
||||
vid = batadv_dat_get_vid(skb, &hdr_size);
|
||||
|
||||
type = batadv_arp_get_type(bat_priv, skb, hdr_size);
|
||||
|
|
@ -1243,6 +1250,10 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
|
|||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
goto out;
|
||||
|
||||
/* first, find out the vid. */
|
||||
if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
|
||||
goto out;
|
||||
|
||||
vid = batadv_dat_get_vid(skb, &hdr_size);
|
||||
|
||||
type = batadv_arp_get_type(bat_priv, skb, hdr_size);
|
||||
|
|
@ -1305,6 +1316,10 @@ void batadv_dat_snoop_outgoing_arp_reply(struct batadv_priv *bat_priv,
|
|||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
return;
|
||||
|
||||
/* first, find out the vid. */
|
||||
if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
|
||||
return;
|
||||
|
||||
vid = batadv_dat_get_vid(skb, &hdr_size);
|
||||
|
||||
type = batadv_arp_get_type(bat_priv, skb, hdr_size);
|
||||
|
|
@ -1353,6 +1368,10 @@ bool batadv_dat_snoop_incoming_arp_reply(struct batadv_priv *bat_priv,
|
|||
if (!READ_ONCE(bat_priv->distributed_arp_table))
|
||||
goto out;
|
||||
|
||||
/* first, find out the vid. */
|
||||
if (!pskb_may_pull(skb, hdr_size + ETH_HLEN))
|
||||
goto out;
|
||||
|
||||
vid = batadv_dat_get_vid(skb, &hdr_size);
|
||||
|
||||
type = batadv_arp_get_type(bat_priv, skb, hdr_size);
|
||||
|
|
@ -1807,6 +1826,10 @@ bool batadv_dat_drop_broadcast_packet(struct batadv_priv *bat_priv,
|
|||
if (batadv_forw_packet_is_rebroadcast(forw_packet))
|
||||
goto out;
|
||||
|
||||
/* first, find out the vid. */
|
||||
if (!pskb_may_pull(forw_packet->skb, hdr_size + ETH_HLEN))
|
||||
goto out;
|
||||
|
||||
vid = batadv_dat_get_vid(forw_packet->skb, &hdr_size);
|
||||
|
||||
type = batadv_arp_get_type(bat_priv, forw_packet->skb, hdr_size);
|
||||
|
|
|
|||
|
|
@ -580,6 +580,9 @@ void batadv_recv_handler_unregister(u8 packet_type)
|
|||
* @skb: the buffer containing the packet
|
||||
* @header_len: length of the batman header preceding the ethernet header
|
||||
*
|
||||
* The caller must ensure that at least @header_len + ETH_HLEN bytes are
|
||||
* accessible after skb->data.
|
||||
*
|
||||
* Return: VID with the BATADV_VLAN_HAS_TAG flag when the packet embedded in the
|
||||
* skb is vlan tagged. Otherwise BATADV_NO_FLAGS.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user