[RH7] packet: fix fanout check race in fanout_add() and fanout_release()

Submitted by Pavel Tikhomirov on Oct. 27, 2017, 4:34 p.m.

Details

Message ID 20171027163412.27621-1-ptikhomirov@virtuozzo.com
State New
Series "packet: fix fanout check race in fanout_add() and fanout_release()"
Headers show

Commit Message

Pavel Tikhomirov Oct. 27, 2017, 4:34 p.m.
There is ms commit d199fab63c11("packet: fix races in fanout_add()")
in which we put fanout checks under fanout_mutex, to remove race
for these functions with each other, race can lead to double add
of same socket to same fanout group, or dereferencing already
removed group.

Skip hunks for rollover and fanout_release_data which we do not have.

https://jira.sw.ru/browse/PSBM-75808

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
 net/packet/af_packet.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

Patch hide | download patch | download mbox

diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 8922fb0e08a8..5118cca2f888 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1380,10 +1380,12 @@  static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
 		return -EINVAL;
 	}
 
+	mutex_lock(&fanout_mutex);
+
+	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 &&
@@ -1450,17 +1452,16 @@  static void fanout_release(struct sock *sk)
 	struct packet_sock *po = pkt_sk(sk);
 	struct packet_fanout *f;
 
-	f = po->fanout;
-	if (!f)
-		return;
-
 	mutex_lock(&fanout_mutex);
-	po->fanout = NULL;
+	f = po->fanout;
+	if (f) {
+		po->fanout = NULL;
 
-	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);
 }