Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp3884153pxv; Mon, 19 Jul 2021 11:04:32 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxzrBYjVASNWtNjNNDD9I214oYduq+QWQUXIov5kLaGf96wfcxbDNM3W4eQ4r+3AgPZymo6 X-Received: by 2002:aa7:c689:: with SMTP id n9mr36132437edq.151.1626717872495; Mon, 19 Jul 2021 11:04:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626717872; cv=none; d=google.com; s=arc-20160816; b=wK8e2GUPy8iwpBqbCMtKAuLsx4stLiv3uWX7yz9p8o+k8lVK82CArfuhz72vLDW25O qqd/37RVW5HHGrquy/PRn+3XLJRj21f8wAeEVRtj4FhA1TA60Ux4CZQzH+mVAAYh1QZT nEU6w5RjiEDcOhStL/Ny1/9RmQhjLpbm1Bf09KwyZZZIKJmu78L3jT04Lg5XB2xeJp/L kkFrvFUMykjOg9WCmrtkZNbPNtQO9hFLxfWoXKpJwLB0FfgnENM/Lyq2OZXI1Zxuh5fQ Bys83hUONn9B4B09j/9YYN3zFvmKwveputSFQaGIZjWk9R+Ur3eXF/pRqQXzTNHuOnnf dsFw== 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=iTvsp6nKY+pbX6Q29vnmUFe4FjP+dcbhJQecSpWzvBs=; b=wIcgt9xWZq7zfnaHsYb398bsj8P2ILrWCaPbeuFH+L6zRBfUKMmnQwmOwsAsi0SjpB tMHg3iw5luaH4OWNHCc9A/ZFR+bAdf1nWB+lPlNCt6LoMA8tZxFub9JasOJGZwDwIVW2 VGK/JvZfQlsWwPRJhTOgkkVkS2iUNmYoB7jl8Z/4/5Zp1kumccBd2ZcD7LjfkDF2/5uF aJdSLLcG8p3BJLktEmpvq7fKY0JGRvMM/cDoS+cJwNItqzUVOXHRJPGM7J43hwAtXGUe qiQljGG/zXyTbL1p1eCkui3yOAdIa5W57h9iWMUHi7LgncEcwfgK63uJNsUVsCNQx3Om Pd2A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=hOBWgwzc; 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 s18si24602875ejh.110.2021.07.19.11.04.09; Mon, 19 Jul 2021 11:04:32 -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=hOBWgwzc; 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 S1377056AbhGSRQG (ORCPT + 99 others); Mon, 19 Jul 2021 13:16:06 -0400 Received: from mail.kernel.org ([198.145.29.99]:36640 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347279AbhGSPjZ (ORCPT ); Mon, 19 Jul 2021 11:39:25 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 2DD2D61264; Mon, 19 Jul 2021 16:18:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626711540; bh=3WBfwcuwGRYVyqJDwmS4N664i6N+pbX2/wBRHuVVNvU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hOBWgwzcqBpTlNy1jwDl1dgEcldM/QO1krrO6qSTlCZdGPSkv1G8ZgsTXZ8louJRO IbhFqAd2eTtcKrndvaoU5k9lsYhw/+46GMBakxSt/u14O7Uy5MJzoC9MjDpqJEIOpX MQPvCkEi2GKKhKDZt1WMAsFi1wbF65jHnVgUC4b8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+dde0cc33951735441301@syzkaller.appspotmail.com, Matthew Wilcox , syzbot+88e4f02896967fe1ab0d@syzkaller.appspotmail.com, Thomas Gleixner , Boqun Feng , "Paul E. McKenney" , Sasha Levin Subject: [PATCH 5.12 039/292] rcu: Reject RCU_LOCKDEP_WARN() false positives Date: Mon, 19 Jul 2021 16:51:41 +0200 Message-Id: <20210719144943.802825080@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210719144942.514164272@linuxfoundation.org> References: <20210719144942.514164272@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: Paul E. McKenney [ Upstream commit 3066820034b5dd4e89bd74a7739c51c2d6f5e554 ] If another lockdep report runs concurrently with an RCU lockdep report from RCU_LOCKDEP_WARN(), the following sequence of events can occur: 1. debug_lockdep_rcu_enabled() sees that lockdep is enabled when called from (say) synchronize_rcu(). 2. Lockdep is disabled by a concurrent lockdep report. 3. debug_lockdep_rcu_enabled() evaluates its lockdep-expression argument, for example, lock_is_held(&rcu_bh_lock_map). 4. Because lockdep is now disabled, lock_is_held() plays it safe and returns the constant 1. 5. But in this case, the constant 1 is not safe, because invoking synchronize_rcu() under rcu_read_lock_bh() is disallowed. 6. debug_lockdep_rcu_enabled() wrongly invokes lockdep_rcu_suspicious(), resulting in a false-positive splat. This commit therefore changes RCU_LOCKDEP_WARN() to check debug_lockdep_rcu_enabled() after checking the lockdep expression, so that any "safe" returns from lock_is_held() are rejected by debug_lockdep_rcu_enabled(). This requires memory ordering, which is supplied by READ_ONCE(debug_locks). The resulting volatile accesses prevent the compiler from reordering and the fact that only one variable is being accessed prevents the underlying hardware from reordering. The combination works for IA64, which can reorder reads to the same location, but this is defeated by the volatile accesses, which compile to load instructions that provide ordering. Reported-by: syzbot+dde0cc33951735441301@syzkaller.appspotmail.com Reported-by: Matthew Wilcox Reported-by: syzbot+88e4f02896967fe1ab0d@syzkaller.appspotmail.com Reported-by: Thomas Gleixner Suggested-by: Boqun Feng Reviewed-by: Boqun Feng Signed-off-by: Paul E. McKenney Signed-off-by: Sasha Levin --- include/linux/rcupdate.h | 2 +- kernel/rcu/update.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index bd04f722714f..d11bee5d9347 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -315,7 +315,7 @@ static inline int rcu_read_lock_any_held(void) #define RCU_LOCKDEP_WARN(c, s) \ do { \ static bool __section(".data.unlikely") __warned; \ - if (debug_lockdep_rcu_enabled() && !__warned && (c)) { \ + if ((c) && debug_lockdep_rcu_enabled() && !__warned) { \ __warned = true; \ lockdep_rcu_suspicious(__FILE__, __LINE__, s); \ } \ diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c index b95ae86c40a7..dd94a602a6d2 100644 --- a/kernel/rcu/update.c +++ b/kernel/rcu/update.c @@ -277,7 +277,7 @@ EXPORT_SYMBOL_GPL(rcu_callback_map); noinstr int notrace debug_lockdep_rcu_enabled(void) { - return rcu_scheduler_active != RCU_SCHEDULER_INACTIVE && debug_locks && + return rcu_scheduler_active != RCU_SCHEDULER_INACTIVE && READ_ONCE(debug_locks) && current->lockdep_recursion == 0; } EXPORT_SYMBOL_GPL(debug_lockdep_rcu_enabled); -- 2.30.2