Received: by 2002:a05:6a10:af89:0:0:0:0 with SMTP id iu9csp3971779pxb; Tue, 25 Jan 2022 00:19:13 -0800 (PST) X-Google-Smtp-Source: ABdhPJz3R5AT1N08GaRS8Rorv7DcZ5uao+3+9aNsqj6fxkBDBcbnel4gH5KDlc8h6SgRRQFXz34H X-Received: by 2002:a17:906:4fcc:: with SMTP id i12mr3126589ejw.530.1643098753085; Tue, 25 Jan 2022 00:19:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1643098753; cv=none; d=google.com; s=arc-20160816; b=DEXRwKbMmbhXtXC6y3DPkyD/n2SOquvkNcuKsKsk5QeVUYW2b4U59neaOGgVDj0Mx1 FT6tespt3XcqDkNnmQwEt4C+rIw+pykOnTdIAq7G7LyNp3P98S63zZVIyCnAQRWrKdI+ GOveVZkRizkVxuA2YZ1sOEQm1C0NDPqBaSc0L6drTr5KGLWC7vyXT3C8/zPr8qPgCnGA g6+NRtdyYrYFh/mYO8IEzAb8RmH59bwSlDFONCUw9obP0Qb9gz5ET92vPG533YnYyad2 TGp+Nni+w5AWZOOrPEwsaYdq2NKAOA6B2VFiD4VoUZ6DYlStTr5DdvlswFZPn4vA72lC WJ0w== 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=Ssqb8CMtcPbshYRxOnmzXm23sDv3CA74Umq7sGql6OE=; b=ljQGGrN1eP67/44PkbrOLNAHolJQRdlqbvHfYKZ4yLVMwTOfx/al2ufpUAg/6j/5TX VWEiElxxgcpNOWtVMgjqPVSQzRpohWWl9oeJNWK8/G33UO/mLz4J942cUO35JazSWnsv OSfRuW1cqiS7tayJhek6PptKasLsEVOpkatS8zMQhycDSUG+OCZCgMaBsC6pbCs2r0WN bsrC1L1WlQzRf4b1+51wWWqn60O01zQIVpEsvV24h/KWQBFyTj7Zl5z9n0k/9NpDZo3n 4ah7p95pOCCU8d5n91/QgPNf1QH1/PJ+pGzlM+ZvNROOlGVsn7GowWDCOce4oGFnWE+a bSbg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b="RKYoqIt/"; 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 m17si10881639edd.153.2022.01.25.00.18.48; Tue, 25 Jan 2022 00:19:13 -0800 (PST) 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="RKYoqIt/"; 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 S3412830AbiAYAhx (ORCPT + 99 others); Mon, 24 Jan 2022 19:37:53 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57808 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2364097AbiAXXqp (ORCPT ); Mon, 24 Jan 2022 18:46:45 -0500 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DA47BC061250; Mon, 24 Jan 2022 13:42:28 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 7AB1360917; Mon, 24 Jan 2022 21:42:28 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5783BC340E4; Mon, 24 Jan 2022 21:42:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1643060547; bh=8gIy0nFAgB03VCQxnZfvFcSa3D+U6k63cyxwaTXRIKc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RKYoqIt/WXqc87JcD8d2UG6UPsFtnp/aA2S4LS5Do95BXAkvI9/7MeHmyq/bSZlAw FGJyuyCAZ/77KkLHR8msHqQ0J+OAyCGcWCBBMHR6ya3jMztywBdVvyz5vqEhCGv2g/ E5hdIDikBZeuN+0If/YHhCQw2MNJuIKZb8u+20zQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Dumazet , "David S. Miller" Subject: [PATCH 5.16 0985/1039] inet: frags: annotate races around fqdir->dead and fqdir->high_thresh Date: Mon, 24 Jan 2022 19:46:14 +0100 Message-Id: <20220124184158.385942525@linuxfoundation.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220124184125.121143506@linuxfoundation.org> References: <20220124184125.121143506@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 commit 91341fa0003befd097e190ec2a4bf63ad957c49a upstream. Both fields can be read/written without synchronization, add proper accessors and documentation. Fixes: d5dd88794a13 ("inet: fix various use-after-free in defrags units") Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/net/inet_frag.h | 11 +++++++++-- include/net/ipv6_frag.h | 3 ++- net/ipv4/inet_fragment.c | 8 +++++--- net/ipv4/ip_fragment.c | 3 ++- 4 files changed, 18 insertions(+), 7 deletions(-) --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h @@ -117,8 +117,15 @@ int fqdir_init(struct fqdir **fqdirp, st static inline void fqdir_pre_exit(struct fqdir *fqdir) { - fqdir->high_thresh = 0; /* prevent creation of new frags */ - fqdir->dead = true; + /* Prevent creation of new frags. + * Pairs with READ_ONCE() in inet_frag_find(). + */ + WRITE_ONCE(fqdir->high_thresh, 0); + + /* Pairs with READ_ONCE() in inet_frag_kill(), ip_expire() + * and ip6frag_expire_frag_queue(). + */ + WRITE_ONCE(fqdir->dead, true); } void fqdir_exit(struct fqdir *fqdir); --- a/include/net/ipv6_frag.h +++ b/include/net/ipv6_frag.h @@ -67,7 +67,8 @@ ip6frag_expire_frag_queue(struct net *ne struct sk_buff *head; rcu_read_lock(); - if (fq->q.fqdir->dead) + /* Paired with the WRITE_ONCE() in fqdir_pre_exit(). */ + if (READ_ONCE(fq->q.fqdir->dead)) goto out_rcu_unlock; spin_lock(&fq->q.lock); --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c @@ -235,9 +235,9 @@ void inet_frag_kill(struct inet_frag_que /* The RCU read lock provides a memory barrier * guaranteeing that if fqdir->dead is false then * the hash table destruction will not start until - * after we unlock. Paired with inet_frags_exit_net(). + * after we unlock. Paired with fqdir_pre_exit(). */ - if (!fqdir->dead) { + if (!READ_ONCE(fqdir->dead)) { rhashtable_remove_fast(&fqdir->rhashtable, &fq->node, fqdir->f->rhash_params); refcount_dec(&fq->refcnt); @@ -352,9 +352,11 @@ static struct inet_frag_queue *inet_frag /* TODO : call from rcu_read_lock() and no longer use refcount_inc_not_zero() */ struct inet_frag_queue *inet_frag_find(struct fqdir *fqdir, void *key) { + /* This pairs with WRITE_ONCE() in fqdir_pre_exit(). */ + long high_thresh = READ_ONCE(fqdir->high_thresh); struct inet_frag_queue *fq = NULL, *prev; - if (!fqdir->high_thresh || frag_mem_limit(fqdir) > fqdir->high_thresh) + if (!high_thresh || frag_mem_limit(fqdir) > high_thresh) return NULL; rcu_read_lock(); --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -144,7 +144,8 @@ static void ip_expire(struct timer_list rcu_read_lock(); - if (qp->q.fqdir->dead) + /* Paired with WRITE_ONCE() in fqdir_pre_exit(). */ + if (READ_ONCE(qp->q.fqdir->dead)) goto out_rcu_unlock; spin_lock(&qp->q.lock);