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

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Fri Oct 27 19:34:12 MSK 2017


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 at virtuozzo.com>
---
 net/packet/af_packet.c | 23 ++++++++++++-----------
 1 file changed, 12 insertions(+), 11 deletions(-)

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);
 }
-- 
2.13.5



More information about the Devel mailing list