Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4751980pxj; Wed, 12 May 2021 12:24:42 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzWsm0YUX6YmwT7U9Qz2DewDSkZMWjW+hAfqJQiHd3jfZeelilQ+ITMcBixACn5cFkB0i0g X-Received: by 2002:a05:6402:c03:: with SMTP id co3mr44769604edb.133.1620847482282; Wed, 12 May 2021 12:24:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620847482; cv=none; d=google.com; s=arc-20160816; b=rxHYatjEoKKZSt6KlcV7nDY84cAB3qX435mOANAOOIozKwoq3BEhrr1tBbGkudfbcm F5vyypRlJJW/2K4KN4X4POJavCbW51YndxstMl0Ju59KtXODGE4nbVtvj0YRweb6vriZ eXh6Cq7gcbP1K3RApFn+vew/x+IUssXXc8BiLvQi+OQEvw1E24IJJgH7N4J/JC/4N6rp 7bLwX43jlp6gqgj84njVxNRXYB7GafCJwsEJNr179o+TYk57PwFj/Ei1tjNj4YnirJPD RS5HCmJvXA6tZDzWPLog3q7KoPdnVZ5eK6gLgwSE6nY4W6ytbZ/9zx3bdMzxVB+R9wnc /cHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=XqOLIbRMh32D6JPbM6FFMlE9w4fn/Jaa+7txLprSx5o=; b=QsKMs8Rle1Hv6QQidj7e5OdMi4HRtG0yJvXQCNsVpghE/KUcphQyW7ub7VhETBsEw5 YvHMO4N+Je0IpY1qpFVdb0UM0ZOKvM+qXQHzj55ctdPAw96FBt9ruFodR1uJG7lwbVue si6sLHSUjOCOnXRtiCud8WYZ7S/af21Q+0Ary5pXZai0WVC1rnoMVyWaZQv+2ZSuGaV3 MLzV/00+O8VhzmU4UUq+6twQHUbizUFaO04i/G80skI6hNKukii/FySuFfD878a0CY5K yk7Zs/mchFzUoeFkL6ki6oMxX20CoGkkgskWX99gzF2hQmvOQ237iZjbSObSTxJ4gh6E 8Ocg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ayYY2Xou; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id bw18si725877ejb.121.2021.05.12.12.24.18; Wed, 12 May 2021 12:24:42 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ayYY2Xou; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1378209AbhELTKv (ORCPT + 99 others); Wed, 12 May 2021 15:10:51 -0400 Received: from mail.kernel.org ([198.145.29.99]:33470 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237887AbhELQnO (ORCPT ); Wed, 12 May 2021 12:43:14 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2D0946147E; Wed, 12 May 2021 16:13:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1620836019; bh=szrUFA494Hiv6N0VCLitWp3BM5Y6zDOyZ/L7tc4cVds=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ayYY2XouUvrbngVuGmbW4t09cYDzCsuqd/GTiHdVEUmOHQ0athP/lh4cST+w6kdaw IDBsKGOYWe5CPYKdM0mKydMiUOuT8P86QYeiPm62cuMWD1JvCtNAjxWmY1KOilw8uV EoFmk9Jmmjf1nRMOiZOyZMW7Mt0QLfnfRn5dIy2k= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Dumazet , "Gong, Sishuai" , Willem de Bruijn , "David S. Miller" , Sasha Levin Subject: [PATCH 5.12 578/677] net/packet: remove data races in fanout operations Date: Wed, 12 May 2021 16:50:24 +0200 Message-Id: <20210512144856.591873791@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210512144837.204217980@linuxfoundation.org> References: <20210512144837.204217980@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Eric Dumazet [ Upstream commit 94f633ea8ade8418634d152ad0931133338226f6 ] af_packet fanout uses RCU rules to ensure f->arr elements are not dismantled before RCU grace period. However, it lacks rcu accessors to make sure KCSAN and other tools wont detect data races. Stupid compilers could also play games. Fixes: dc99f600698d ("packet: Add fanout support.") Signed-off-by: Eric Dumazet Reported-by: "Gong, Sishuai" Cc: Willem de Bruijn Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/packet/af_packet.c | 15 +++++++++------ net/packet/internal.h | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index e24b2841c643..9611e41c7b8b 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -1359,7 +1359,7 @@ static unsigned int fanout_demux_rollover(struct packet_fanout *f, struct packet_sock *po, *po_next, *po_skip = NULL; unsigned int i, j, room = ROOM_NONE; - po = pkt_sk(f->arr[idx]); + po = pkt_sk(rcu_dereference(f->arr[idx])); if (try_self) { room = packet_rcv_has_room(po, skb); @@ -1371,7 +1371,7 @@ static unsigned int fanout_demux_rollover(struct packet_fanout *f, i = j = min_t(int, po->rollover->sock, num - 1); do { - po_next = pkt_sk(f->arr[i]); + po_next = pkt_sk(rcu_dereference(f->arr[i])); if (po_next != po_skip && !READ_ONCE(po_next->pressure) && packet_rcv_has_room(po_next, skb) == ROOM_NORMAL) { if (i != j) @@ -1466,7 +1466,7 @@ static int packet_rcv_fanout(struct sk_buff *skb, struct net_device *dev, if (fanout_has_flag(f, PACKET_FANOUT_FLAG_ROLLOVER)) idx = fanout_demux_rollover(f, skb, idx, true, num); - po = pkt_sk(f->arr[idx]); + po = pkt_sk(rcu_dereference(f->arr[idx])); return po->prot_hook.func(skb, dev, &po->prot_hook, orig_dev); } @@ -1480,7 +1480,7 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po) struct packet_fanout *f = po->fanout; spin_lock(&f->lock); - f->arr[f->num_members] = sk; + rcu_assign_pointer(f->arr[f->num_members], sk); smp_wmb(); f->num_members++; if (f->num_members == 1) @@ -1495,11 +1495,14 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po) spin_lock(&f->lock); for (i = 0; i < f->num_members; i++) { - if (f->arr[i] == sk) + if (rcu_dereference_protected(f->arr[i], + lockdep_is_held(&f->lock)) == sk) break; } BUG_ON(i >= f->num_members); - f->arr[i] = f->arr[f->num_members - 1]; + rcu_assign_pointer(f->arr[i], + rcu_dereference_protected(f->arr[f->num_members - 1], + lockdep_is_held(&f->lock))); f->num_members--; if (f->num_members == 0) __dev_remove_pack(&f->prot_hook); diff --git a/net/packet/internal.h b/net/packet/internal.h index 5f61e59ebbff..48af35b1aed2 100644 --- a/net/packet/internal.h +++ b/net/packet/internal.h @@ -94,7 +94,7 @@ struct packet_fanout { spinlock_t lock; refcount_t sk_ref; struct packet_type prot_hook ____cacheline_aligned_in_smp; - struct sock *arr[]; + struct sock __rcu *arr[]; }; struct packet_rollover { -- 2.30.2