Skip to contentSkip to conversation

batman-adv: check return type of unicast packet preparations

PATCH In review Linus Lüssing 2 participants 3 messages Jul 26, 2013

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 batman-adv: check return type of unicast packet preparations

batadv_send_skb_prepare_unicast(_4addr) might reallocate the skb's data. And if it tries to do so then this can potentially fail.

We shouldn't continue working on this skb in such a case.

---
 send.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
send.c +6 -3
index d2cc507..9c9cab6 100644
@@ -266,11 +266,14 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
 
 	switch (packet_type) {
 	case BATADV_UNICAST:
-		batadv_send_skb_prepare_unicast(skb, orig_node);
+		if (!batadv_send_skb_prepare_unicast(skb, orig_node))
+			goto out;
 		break;
 	case BATADV_UNICAST_4ADDR:
-		batadv_send_skb_prepare_unicast_4addr(bat_priv, skb, orig_node,
-						      packet_subtype);
+		if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, skb,
+							   orig_node,
+							   packet_subtype))
+			goto out;
 		break;
 	default:
 		/* this function supports UNICAST and UNICAST_4ADDR only. It
Signature · 1 line
1.7.10.4
#1 lore raw

PATCH 2/2 batman-adv: fix potential kernel paging error for unicast transmissions

batadv_send_skb_prepare_unicast(_4addr) might reallocate the skb's data. If it does then our ethhdr pointer is not valid anymore in batadv_send_skb_unicast(), resulting in a kernel paging error.

This patch fixes this issue by storing the few bytes we are interested in on the stack before modifying the skb.

---
 send.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
send.c +4 -2
index 9c9cab6..b9a1f15 100644
@@ -257,13 +257,15 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
 				   struct batadv_orig_node *orig_node,
 				   unsigned short vid)
 {
-	struct ethhdr *ethhdr = (struct ethhdr *)skb->data;
+	uint8_t dest[ETH_ALEN];
 	struct batadv_unicast_packet *unicast_packet;
 	int ret = NET_XMIT_DROP;
 
 	if (!orig_node)
 		goto out;
 
+	memcpy(dest, ((struct ethhdr *)skb->data)->h_dest, sizeof(dest));
+
 	switch (packet_type) {
 	case BATADV_UNICAST:
 		if (!batadv_send_skb_prepare_unicast(skb, orig_node))
@@ -289,7 +291,7 @@ static int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
 	 * try to reroute it because the ttvn contained in the header is less
 	 * than the current one
 	 */
-	if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest, vid))
+	if (batadv_tt_global_client_is_roaming(bat_priv, dest, vid))
 		unicast_packet->ttvn = unicast_packet->ttvn - 1;
 
 	if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
Signature · 1 line
1.7.10.4
#2 lore raw
In reply to Linus Lüssing

Hi Linus,

since these are two fixes, are those based on top of next? That is where they should be applied.

Cheers,

Il 26.07.2013 20:50 Linus Lüssing ha scritto:

Quoted 33 lines

batadv_send_skb_prepare_unicast(_4addr) might reallocate the skb's data. And if it tries to do so then this can potentially fail.

We shouldn't continue working on this skb in such a case.

---
 send.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
send.c +6 -3
index d2cc507..9c9cab6 100644
@@ -266,11 +266,14 @@ static int batadv_send_skb_unicast(struct
 batadv_priv *bat_priv,
 
 	switch (packet_type) {
 	case BATADV_UNICAST:
-		batadv_send_skb_prepare_unicast(skb, orig_node);
+		if (!batadv_send_skb_prepare_unicast(skb, orig_node))
+			goto out;
 		break;
 	case BATADV_UNICAST_4ADDR:
-		batadv_send_skb_prepare_unicast_4addr(bat_priv, skb, orig_node,
-						      packet_subtype);
+		if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, skb,
+							   orig_node,
+							   packet_subtype))
+			goto out;
 		break;
 	default:

/* this function supports UNICAST and UNICAST_4ADDR only. It

Signature · 1 line
Antonio Quartulli