Commit 6e54ea37 authored by Paolo Abeni's avatar Paolo Abeni Committed by David S. Miller

net: mctp: hold key reference when looking up a general key

Currently, we have a race where we look up a sock through a "general"
(ie, not directly associated with the (src,dest,tag) tuple) key, then
drop the key reference while still holding the key's sock.

This change expands the key reference until we've finished using the
sock, and hence the sock reference too.

Commit message changes from Jeremy Kerr <jk@codeconstruct.com.au>.
Reported-by: default avatarNoam Rathaus <noamr@ssd-disclosure.com>
Fixes: 73c61845 ("mctp: locking, lifetime and validity changes for sk_keys")
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarJeremy Kerr <jk@codeconstruct.com.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5f41ae6f
...@@ -317,8 +317,8 @@ static int mctp_frag_queue(struct mctp_sk_key *key, struct sk_buff *skb) ...@@ -317,8 +317,8 @@ static int mctp_frag_queue(struct mctp_sk_key *key, struct sk_buff *skb)
static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb) static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
{ {
struct mctp_sk_key *key, *any_key = NULL;
struct net *net = dev_net(skb->dev); struct net *net = dev_net(skb->dev);
struct mctp_sk_key *key;
struct mctp_sock *msk; struct mctp_sock *msk;
struct mctp_hdr *mh; struct mctp_hdr *mh;
unsigned long f; unsigned long f;
...@@ -363,13 +363,11 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb) ...@@ -363,13 +363,11 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
* key for reassembly - we'll create a more specific * key for reassembly - we'll create a more specific
* one for future packets if required (ie, !EOM). * one for future packets if required (ie, !EOM).
*/ */
key = mctp_lookup_key(net, skb, MCTP_ADDR_ANY, &f); any_key = mctp_lookup_key(net, skb, MCTP_ADDR_ANY, &f);
if (key) { if (any_key) {
msk = container_of(key->sk, msk = container_of(any_key->sk,
struct mctp_sock, sk); struct mctp_sock, sk);
spin_unlock_irqrestore(&key->lock, f); spin_unlock_irqrestore(&any_key->lock, f);
mctp_key_unref(key);
key = NULL;
} }
} }
...@@ -475,6 +473,8 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb) ...@@ -475,6 +473,8 @@ static int mctp_route_input(struct mctp_route *route, struct sk_buff *skb)
spin_unlock_irqrestore(&key->lock, f); spin_unlock_irqrestore(&key->lock, f);
mctp_key_unref(key); mctp_key_unref(key);
} }
if (any_key)
mctp_key_unref(any_key);
out: out:
if (rc) if (rc)
kfree_skb(skb); kfree_skb(skb);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment