b.a.t.m.a.n.lists.open-mesh.org archive mirror
 help / color / mirror / Atom feed
From: Sven Eckelmann <sven@narfation.org>
To: b.a.t.m.a.n@lists.open-mesh.org
Cc: "Martin Hundebøll" <martin@hundeboll.net>,
	"Marek Lindner" <mareklindner@neomailbox.ch>,
	"Antonio Quartulli" <antonio@meshcoding.com>
Subject: [B.A.T.M.A.N.] Missing list checks for *list_add*
Date: Fri, 26 Jun 2015 16:45:01 +0200	[thread overview]
Message-ID: <1898798.WP4bC1arXA@bentobox> (raw)

[-- Attachment #1: Type: text/plain, Size: 2638 bytes --]

Hi,

Simon debugged the refcnt problem and submitted some patches to fix them. I
had a brief look and noticed that there are possible more problems similar to
the *list_del* ones - just with *list_add*. Basically some functions use some
kind of get function, notice that the element does not exist and then create
a new one to add to the list. Only the "list_add" is protected. The result may
be that an element in twice in a list when only a single occurrence is allowed.

The problem I saw is batadv_gw_node_update. It first calls batadv_gw_node_get
to check if an object with this value already exists and then uses
batadv_gw_node_add to add a node (which may already be added between these
two calls). So it has to be made sure that nothing modifies the list between
these two calls).

Similar looking functions are for example:

 * batadv_tvlv_handler_register
 * batadv_nc_get_nc_node
 * batadv_softif_create_vlan
 * batadv_tt_global_orig_entry_add

Just for illustration what I meant with "nothing modifies the list between
these two calls":

--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -30,6 +30,7 @@
 #include <linux/jiffies.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
+#include <linux/lockdep.h>
 #include <linux/netdevice.h>
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
@@ -425,6 +426,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
 {
 	struct batadv_gw_node *gw_node;
 
+	lockdep_assert_held(&bat_priv->gw.list_lock);
+
 	if (gateway->bandwidth_down == 0)
 		return;
 
@@ -441,9 +444,7 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
 	gw_node->orig_node = orig_node;
 	atomic_set(&gw_node->refcount, 1);
 
-	spin_lock_bh(&bat_priv->gw.list_lock);
 	hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.list);
-	spin_unlock_bh(&bat_priv->gw.list_lock);
 
 	batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
 		   "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
@@ -497,11 +498,14 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
 	struct batadv_gw_node *gw_node, *gw_node_tmp, *curr_gw = NULL;
 	struct hlist_node *node_tmp;
 
+	spin_lock_bh(&bat_priv->gw.list_lock);
 	gw_node = batadv_gw_node_get(bat_priv, orig_node);
 	if (!gw_node) {
 		batadv_gw_node_add(bat_priv, orig_node, gateway);
+		spin_unlock_bh(&bat_priv->gw.list_lock);
 		goto out;
 	}
+	spin_unlock_bh(&bat_priv->gw.list_lock);
 
 	if ((gw_node->bandwidth_down == ntohl(gateway->bandwidth_down)) &&
 	    (gw_node->bandwidth_up == ntohl(gateway->bandwidth_up)))


Kind regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

             reply	other threads:[~2015-06-26 14:45 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-26 14:45 Sven Eckelmann [this message]
2015-07-26  0:41 ` [B.A.T.M.A.N.] Missing list checks for *list_add* Sven Eckelmann

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1898798.WP4bC1arXA@bentobox \
    --to=sven@narfation.org \
    --cc=antonio@meshcoding.com \
    --cc=b.a.t.m.a.n@lists.open-mesh.org \
    --cc=mareklindner@neomailbox.ch \
    --cc=martin@hundeboll.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).