netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Graf <tgraf@suug.ch>
To: Cong Wang <cwang@twopensource.com>, davem@davemloft.net
Cc: Andrey Wagin <avagin@gmail.com>, netdev <netdev@vger.kernel.org>
Subject: [PATCH net] netlink: hold nl_sock_hash_lock during diag dump
Date: Thu, 7 Aug 2014 00:18:47 +0100	[thread overview]
Message-ID: <20140806231847.GA3703@casper.infradead.org> (raw)
In-Reply-To: <CAHA+R7OB_gTYPKtqw-iry+nfkTbmApw4GPpeKjqfXugcit4Guw@mail.gmail.com>

On 08/06/14 at 02:20pm, Cong Wang wrote:
> On Wed, Aug 6, 2014 at 12:51 PM, Thomas Graf <tgraf@suug.ch> wrote:
> > On 08/06/14 at 10:52am, Cong Wang wrote:
> >>
> >> Looks like we should hold rcu_read_lock() before calling __netlink_diag_dump().
> >
> > netlink_diag_dump() still acquires nl_table_lock which is pointless as
> > a separate mutex has been introduced to protect mutations. I will send
> > a patch to RCU'ify it properly.
> 
> Agreed, but that's likely a net-next material.
> 
> I think we need the following quick fix for net.

I came up with the exact same patch as you first but eventually
figured holding the mutex directly as below ias actually better
in this case:

[PATCH net] netlink: hold nl_sock_hash_lock during diag dump

Although RCU protection would be possible during diag dump, doing
so allows for concurrent table mutations which can render the
in-table offset between individual Netlink messages invalid and
thus cause legitimate sockets to be skipped in the dump.

Since the diag dump is relatively low volume and consistency is
more important than performance, the table mutex is held during
dump.

Reported-by: Andrey Wagin <avagin@gmail.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Fixes: e341694e3eb57fc ("netlink: Convert netlink_lookup() to use RCU protected hash table")
---
 net/netlink/af_netlink.c | 1 +
 net/netlink/af_netlink.h | 1 +
 net/netlink/diag.c       | 3 +++
 3 files changed, 5 insertions(+)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 479a344..a324b4b 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -104,6 +104,7 @@ static atomic_t nl_table_users = ATOMIC_INIT(0);
 
 /* Protects netlink socket hash table mutations */
 DEFINE_MUTEX(nl_sk_hash_lock);
+EXPORT_SYMBOL_GPL(nl_sk_hash_lock);
 
 static int lockdep_nl_sk_hash_is_held(void)
 {
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
index 60f631f..b20a173 100644
--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -73,5 +73,6 @@ struct netlink_table {
 
 extern struct netlink_table *nl_table;
 extern rwlock_t nl_table_lock;
+extern struct mutex nl_sk_hash_lock;
 
 #endif
diff --git a/net/netlink/diag.c b/net/netlink/diag.c
index 7301850..de8c74a 100644
--- a/net/netlink/diag.c
+++ b/net/netlink/diag.c
@@ -170,6 +170,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
 
 	req = nlmsg_data(cb->nlh);
 
+	mutex_lock(&nl_sk_hash_lock);
 	read_lock(&nl_table_lock);
 
 	if (req->sdiag_protocol == NDIAG_PROTO_ALL) {
@@ -183,6 +184,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
 	} else {
 		if (req->sdiag_protocol >= MAX_LINKS) {
 			read_unlock(&nl_table_lock);
+			mutex_unlock(&nl_sk_hash_lock);
 			return -ENOENT;
 		}
 
@@ -190,6 +192,7 @@ static int netlink_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
 	}
 
 	read_unlock(&nl_table_lock);
+	mutex_unlock(&nl_sk_hash_lock);
 
 	return skb->len;
 }
-- 
1.9.3

  reply	other threads:[~2014-08-06 23:18 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-06 17:29 linux-next: net/netlink/diag.c:106 suspicious rcu_dereference_protected() usage! Andrey Wagin
2014-08-06 17:52 ` Cong Wang
2014-08-06 19:51   ` Thomas Graf
2014-08-06 21:20     ` Cong Wang
2014-08-06 23:18       ` Thomas Graf [this message]
2014-08-07  2:18         ` [PATCH net] netlink: hold nl_sock_hash_lock during diag dump David Miller

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=20140806231847.GA3703@casper.infradead.org \
    --to=tgraf@suug.ch \
    --cc=avagin@gmail.com \
    --cc=cwang@twopensource.com \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    /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).