summaryrefslogtreecommitdiff
path: root/net/netlink/diag.c
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2014-08-06 23:18:47 (GMT)
committerDavid S. Miller <davem@davemloft.net>2014-08-07 02:17:44 (GMT)
commit6c8f7e70837468da4e658080d4448930fb597e1b (patch)
treeb16af5d1fcabe792f0b565d9fca2686cad480efd /net/netlink/diag.c
parent9ea88a153001ffeb3d8810917e8eea62ca9b6f25 (diff)
downloadlinux-6c8f7e70837468da4e658080d4448930fb597e1b.tar.xz
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") Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink/diag.c')
-rw-r--r--net/netlink/diag.c3
1 files changed, 3 insertions, 0 deletions
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;
}