From patchwork Thu Mar 3 20:39:16 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 876 Return-Path: Received: from v3-1039.vlinux.de (narfation.org [79.140.41.39]) by open-mesh.org (Postfix) with ESMTPS id DAC14154033 for ; Thu, 3 Mar 2011 21:39:20 +0100 (CET) Authentication-Results: open-mesh.org; dkim=pass (1024-bit key) header.i=@narfation.org; dkim-adsp=pass Received: from sven-desktop.home.narfation.org (i59F6A524.versanet.de [89.246.165.36]) by v3-1039.vlinux.de (Postfix) with ESMTPSA id 744EE940BE; Thu, 3 Mar 2011 21:39:19 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=narfation.org; s=mail; t=1299184760; bh=gMBoNRheuLTPz7BP3brcIHyXwHwPCSaqXPN1g3cxdD4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type:Content-Transfer-Encoding; b=Jf0nwWtXimpgXUe47IJ+mFV59Hbh07Y6Qjj/PYD1IuoprprIqkZJYB6PGB4RBSxVo ylNmlG+asvp9U1eAwwsigYGsD/Ba7FM8QiydZ2K5XrIWPLS2rgykY6YlwsMinQw0Z9 vZAEQQI2dbxcVUmZPstEV+wBKqZh/RbAoo7MJKAA= From: Sven Eckelmann To: b.a.t.m.a.n@lists.open-mesh.org Date: Thu, 3 Mar 2011 21:39:16 +0100 Message-Id: <1299184756-26069-1-git-send-email-sven@narfation.org> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1299179342-15418-1-git-send-email-linus.luessing@ascom.ch> References: <1299179342-15418-1-git-send-email-linus.luessing@ascom.ch> MIME-Version: 1.0 Subject: [B.A.T.M.A.N.] [PATCH] batman-adv: Fix null pointer deref. when adding hard-if as soft-if X-BeenThere: b.a.t.m.a.n@lists.open-mesh.org X-Mailman-Version: 2.1.13 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Mar 2011 20:39:21 -0000 When we are trying to create a batman soft-interface which already exists as a common hard interface, batman 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. Reported-by: Linus Lüssing Signed-off-by: Sven Eckelmann --- batman-adv/hard-interface.c | 37 +++++++++++++++++++++++-------------- batman-adv/soft-interface.c | 13 +++++++++++++ batman-adv/soft-interface.h | 1 + 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/batman-adv/hard-interface.c b/batman-adv/hard-interface.c index 95a35b6..947e647 100644 --- a/batman-adv/hard-interface.c +++ b/batman-adv/hard-interface.c @@ -71,21 +71,14 @@ static int is_valid_iface(struct net_device *net_dev) { if (net_dev->flags & IFF_LOOPBACK) return 0; - if (net_dev->type != ARPHRD_ETHER) return 0; - if (net_dev->addr_len != ETH_ALEN) return 0; /* no batman over batman */ -#ifdef HAVE_NET_DEVICE_OPS - if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) + if (softif_is_valid(net_dev)) return 0; -#else - if (net_dev->hard_start_xmit == interface_tx) - return 0; -#endif /* Device is being bridged */ /* if (net_dev->priv_flags & IFF_BRIDGE_PORT) @@ -282,6 +275,8 @@ int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name) { struct bat_priv *bat_priv; struct batman_packet *batman_packet; + int ret; + struct net_device *soft_iface; if (hard_iface->if_status != IF_NOT_IN_USE) goto out; @@ -289,18 +284,31 @@ int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name) if (!atomic_inc_not_zero(&hard_iface->refcount)) goto out; - hard_iface->soft_iface = dev_get_by_name(&init_net, iface_name); + soft_iface = dev_get_by_name(&init_net, iface_name); - if (!hard_iface->soft_iface) { - hard_iface->soft_iface = softif_create(iface_name); + if (!soft_iface) { + soft_iface = softif_create(iface_name); - if (!hard_iface->soft_iface) + if (!soft_iface) { + ret = -ENOMEM; goto err; + } /* dev_get_by_name() increases the reference counter for us */ - dev_hold(hard_iface->soft_iface); + dev_hold(soft_iface); } + if (!softif_is_valid(soft_iface)) { + pr_err("Can't create soft interface %s: " + "already exists as non soft interface\n", + soft_iface->name); + dev_put(soft_iface); + ret = -EINVAL; + goto err; + } + + hard_iface->soft_iface = soft_iface; + bat_priv = netdev_priv(hard_iface->soft_iface); hard_iface->packet_len = BAT_PACKET_LEN; hard_iface->packet_buff = kmalloc(hard_iface->packet_len, GFP_ATOMIC); @@ -308,6 +316,7 @@ int hardif_enable_interface(struct hard_iface *hard_iface, char *iface_name) 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 +379,7 @@ out: err: hardif_free_ref(hard_iface); - return -ENOMEM; + return ret; } void hardif_disable_interface(struct hard_iface *hard_iface) diff --git a/batman-adv/soft-interface.c b/batman-adv/soft-interface.c index 6b514ec..9ed2614 100644 --- a/batman-adv/soft-interface.c +++ b/batman-adv/soft-interface.c @@ -622,6 +622,19 @@ void softif_destroy(struct net_device *soft_iface) unregister_netdevice(soft_iface); } +int softif_is_valid(struct net_device *net_dev) +{ +#ifdef HAVE_NET_DEVICE_OPS + if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) + return 1; +#else + if (net_dev->hard_start_xmit == interface_tx) + return 1; +#endif + + return 0; +} + /* ethtool */ static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { diff --git a/batman-adv/soft-interface.h b/batman-adv/soft-interface.h index 80a3607..4789b6f 100644 --- a/batman-adv/soft-interface.h +++ b/batman-adv/soft-interface.h @@ -31,5 +31,6 @@ void interface_rx(struct net_device *soft_iface, int hdr_size); struct net_device *softif_create(char *name); void softif_destroy(struct net_device *soft_iface); +int softif_is_valid(struct net_device *net_dev); #endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */