RFC: batman-adv: Fix null pointer deref. when adding hard-if as soft-if

Message ID 1299179342-15418-2-git-send-email-linus.luessing@ascom.ch (mailing list archive)
State RFC, archived
Headers

Commit Message

Linus Lüssing March 3, 2011, 7:09 p.m. UTC
  When we are trying to create a batman soft-interface which already
exists as a common hard interface, batman than wrongly assumes that this
hard interface is a fully initialized soft interface. This leads to a
null pointer dereference on the first try of accessing for instance a
non-intialized orig_hash.

For every hard interface, there is no initialized orig_hash, therefore
this commit uses this criteria to abort creating a soft interface with
an already existing name.
---
 hard-interface.c |   17 +++++++++++++++--
 1 files changed, 15 insertions(+), 2 deletions(-)
  

Patch

diff --git a/batman-adv/hard-interface.c b/batman-adv/hard-interface.c
index 95a35b6..53d6fce 100644
--- a/batman-adv/hard-interface.c
+++ b/batman-adv/hard-interface.c
@@ -282,6 +282,7 @@  int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name)
 {
 	struct bat_priv *bat_priv;
 	struct batman_packet *batman_packet;
+	int ret;
 
 	if (hard_iface->if_status != IF_NOT_IN_USE)
 		goto out;
@@ -294,20 +295,32 @@  int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name)
 	if (!hard_iface->soft_iface) {
 		hard_iface->soft_iface = softif_create(iface_name);
 
-		if (!hard_iface->soft_iface)
+		if (!hard_iface->soft_iface) {
+			ret = -ENOMEM;
 			goto err;
+		}
 
 		/* dev_get_by_name() increases the reference counter for us */
 		dev_hold(hard_iface->soft_iface);
 	}
 
 	bat_priv = netdev_priv(hard_iface->soft_iface);
+
+	if (!bat_priv->orig_hash) {
+		bat_err(hard_iface->soft_iface,
+			"Can't create soft interface %s: "
+			"already exists as non soft interface\n",
+			hard_iface->soft_iface->name);
+		ret = -EINVAL;
+		goto err;
+	}
 	hard_iface->packet_len = BAT_PACKET_LEN;
 	hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC);
 
 	if (!hard_iface->packet_buff) {
 		bat_err(hard_iface->soft_iface, "Can't add interface packet "
 			"(%s): out of memory\n", hard_iface->net_dev->name);
+		ret = -ENOMEM;
 		goto err;
 	}
 
@@ -370,7 +383,7 @@  out:
 
 err:
 	hardif_free_ref(hard_iface);
-	return -ENOMEM;
+	return ret;
 }
 
 void hardif_disable_interface(struct hard_iface *hard_iface)