aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2017-02-14 09:03:51 -0800
committerJoey Rizzoli <joey@lineageos.org>2017-05-02 14:25:43 +0200
commitd863cfb3fadf2ac6d2958e82753f104523ce322e (patch)
tree5dfc2ee8a8d608012f6fe15b0b92a9304889ca72
parent483c68bd94bcc7a1c59f8a415ee29cfae53ac934 (diff)
fix mismerge: packet: fix races in fanout_add()
Change-Id: I68cfd6fcf94d494e2e93f142fb555250331ab13f
-rw-r--r--net/packet/af_packet.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 8d2d0e4e505..520c88fcfe3 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1285,13 +1285,16 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
return -EINVAL;
}
+ mutex_lock(&fanout_mutex);
+
+ err = -EINVAL;
if (!po->running)
- return -EINVAL;
+ goto out;
+ err = -EALREADY;
if (po->fanout)
- return -EALREADY;
+ goto out;
- mutex_lock(&fanout_mutex);
match = NULL;
list_for_each_entry(f, &fanout_list, list) {
if (f->id == id &&
@@ -1347,17 +1350,16 @@ static void fanout_release(struct sock *sk)
struct packet_sock *po = pkt_sk(sk);
struct packet_fanout *f;
+ mutex_lock(&fanout_mutex);
f = po->fanout;
- if (!f)
- return;
+ if (f) {
+ po->fanout = NULL;
- po->fanout = NULL;
-
- mutex_lock(&fanout_mutex);
- if (atomic_dec_and_test(&f->sk_ref)) {
- list_del(&f->list);
- dev_remove_pack(&f->prot_hook);
- kfree(f);
+ if (atomic_dec_and_test(&f->sk_ref)) {
+ list_del(&f->list);
+ dev_remove_pack(&f->prot_hook);
+ kfree(f);
+ }
}
mutex_unlock(&fanout_mutex);
}