From patchwork Fri Jul 12 17:00:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joel Fernandes X-Patchwork-Id: 11042527 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 80B67138D for ; Fri, 12 Jul 2019 17:00:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6C90C28961 for ; Fri, 12 Jul 2019 17:00:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 603BC2894D; Fri, 12 Jul 2019 17:00:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5FD3285CE for ; Fri, 12 Jul 2019 17:00:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727351AbfGLRAe (ORCPT ); Fri, 12 Jul 2019 13:00:34 -0400 Received: from mail-pl1-f194.google.com ([209.85.214.194]:36565 "EHLO mail-pl1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727342AbfGLRAe (ORCPT ); Fri, 12 Jul 2019 13:00:34 -0400 Received: by mail-pl1-f194.google.com with SMTP id k8so5063505plt.3 for ; Fri, 12 Jul 2019 10:00:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=joelfernandes.org; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=4R73ECcFsgEJ+nDrVGaF7lXHe3UNCLl3CB9t/q9lNT4=; b=QUdJPbnULiAaQGPSi2mqi0K5L8ZUkC7IX+RSaHrjNxvLiFWoKFYBoo/oGR4kaJ+If5 H+hJo/HgYMGa2Q0AVqNqfSZ4wCuzsyweIdbuCBwCruxs20caVT8lckLIacvRNFQKWd4U 5aEnPHEBflrCxzDnwhzGkmd+pAsgTBSfog6z8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=4R73ECcFsgEJ+nDrVGaF7lXHe3UNCLl3CB9t/q9lNT4=; b=ltUpwQ1DIYOgp9KAE4kukVWXvAFo5Q+eG6BmI80ZxXKNTOBiizn9JU9SoqW1Kpu4Is 4PdeuYSFme6K9XfYo+5F8O0KrmY5o7HfOpUiefjQTbamDLGgXg+LHZKOChpM0JcwapxS Akz3qAiW21pjk74yV4PivU8zNHXvk9mQoz0rOcMrsum8nBFbAPEk2DvIERyQtz6NNvsp Fdx2CAWFkD50GoYkEDMbBQqdM2h/uDBzqtgsP+hK8yAMmTdyHmwIyW3H7UCdDkIfnMUo ZhtJe04hWuOQJKur7b50DzTx+fjZ1ZQkv+LtsRIv0fTcT5fTS9FTSdemAgCmrlvxi1i0 XptA== X-Gm-Message-State: APjAAAUJL+BUMBJa8pQ9P3ZM4pUCQChSihxIpO3yGAp0MIUi33m4ylvD rMFccPR3tSGINyTkMJS0Qxs= X-Google-Smtp-Source: APXvYqy/IfEk1KCS4o5ZDngZgPwSlK051hwLHg+0U99vqOwQGBX28IMyNjvCo8ritYeQERfyu/T2Kw== X-Received: by 2002:a17:902:296a:: with SMTP id g97mr12356829plb.115.1562950833539; Fri, 12 Jul 2019 10:00:33 -0700 (PDT) Received: from joelaf.cam.corp.google.com ([2620:15c:6:12:9c46:e0da:efbf:69cc]) by smtp.gmail.com with ESMTPSA id a15sm7127385pgw.3.2019.07.12.10.00.29 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Fri, 12 Jul 2019 10:00:32 -0700 (PDT) From: "Joel Fernandes (Google)" To: linux-kernel@vger.kernel.org Cc: "Joel Fernandes (Google)" , Alexey Kuznetsov , Bjorn Helgaas , Borislav Petkov , c0d1n61at3@gmail.com, "David S. Miller" , edumazet@google.com, Greg Kroah-Hartman , Hideaki YOSHIFUJI , "H. Peter Anvin" , Ingo Molnar , Jonathan Corbet , Josh Triplett , keescook@chromium.org, kernel-hardening@lists.openwall.com, kernel-team@android.com, Lai Jiangshan , Len Brown , linux-acpi@vger.kernel.org, linux-doc@vger.kernel.org, linux-pci@vger.kernel.org, linux-pm@vger.kernel.org, Mathieu Desnoyers , neilb@suse.com, netdev@vger.kernel.org, Oleg Nesterov , "Paul E. McKenney" , Pavel Machek , peterz@infradead.org, "Rafael J. Wysocki" , Rasmus Villemoes , rcu@vger.kernel.org, Steven Rostedt , Tejun Heo , Thomas Gleixner , will@kernel.org, x86@kernel.org (maintainer:X86 ARCHITECTURE (32-BIT AND 64-BIT)) Subject: [PATCH v2 0/9] Harden list_for_each_entry_rcu() and family Date: Fri, 12 Jul 2019 13:00:15 -0400 Message-Id: <20190712170024.111093-1-joel@joelfernandes.org> X-Mailer: git-send-email 2.22.0.510.g264f2c817a-goog MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi, This series aims to provide lockdep checking to RCU list macros for additional kernel hardening. RCU has a number of primitives for "consumption" of an RCU protected pointer. Most of the time, these consumers make sure that such accesses are under a RCU reader-section (such as rcu_dereference{,sched,bh} or under a lock, such as with rcu_dereference_protected()). However, there are other ways to consume RCU pointers, such as by list_for_each_entry_rcu or hlist_for_each_enry_rcu. Unlike the rcu_dereference family, these consumers do no lockdep checking at all. And with the growing number of RCU list uses (1000+), it is possible for bugs to creep in and go unnoticed which lockdep checks can catch. Since RCU consolidation efforts last year, the different traditional RCU flavors (preempt, bh, sched) are all consolidated. In other words, any of these flavors can cause a reader section to occur and all of them must cease before the reader section is considered to be unlocked. Thanks to this, we can generically check if we are in an RCU reader. This is what patch 1 does. Note that the list_for_each_entry_rcu and family are different from the rcu_dereference family in that, there is no _bh or _sched version of this macro. They are used under many different RCU reader flavors, and also SRCU. Patch 1 adds a new internal function rcu_read_lock_any_held() which checks if any reader section is active at all, when these macros are called. If no reader section exists, then the optional fourth argument to list_for_each_entry_rcu() can be a lockdep expression which is evaluated (similar to how rcu_dereference_check() works). If no lockdep expression is passed, and we are not in a reader, then a splat occurs. Just take off the lockdep expression after applying the patches, by using the following diff and see what happens: +++ b/arch/x86/pci/mmconfig-shared.c @@ -55,7 +55,7 @@ static void list_add_sorted(struct pci_mmcfg_region *new) struct pci_mmcfg_region *cfg; /* keep list sorted by segment and starting bus number */ - list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list, pci_mmcfg_lock_held()) { + list_for_each_entry_rcu(cfg, &pci_mmcfg_list, list) { The optional argument trick to list_for_each_entry_rcu() can also be used in the future to possibly remove rcu_dereference_{,bh,sched}_protected() API and we can pass an optional lockdep expression to rcu_dereference() itself. Thus eliminating 3 more RCU APIs. Note that some list macro wrappers already do their own lockdep checking in the caller side. These can be eliminated in favor of the built-in lockdep checking in the list macro that this series adds. For example, workqueue code has a assert_rcu_or_wq_mutex() function which is called in for_each_wq(). This series replaces that in favor of the built-in check. Also in the future, we can extend these checks to list_entry_rcu() and other list macros as well, if needed. Please note that I have kept this option default-disabled under a new config: CONFIG_PROVE_RCU_LIST. This is so that until all users are converted to pass the optional argument, we should keep the check disabled. There are about a 1000 or so users and it is not possible to pass in the optional lockdep expression in a single series since it is done on a case-by-case basis. I did convert a few users in this series itself. v1->v2: Have assert_rcu_or_wq_mutex deleted (Daniel Jordan) Simplify rcu_read_lock_any_held() (Peter Zijlstra) Simplified rcu-sync logic (Oleg Nesterov) Updated documentation and rculist comments. Added GregKH ack. RFC->v1: Simplify list checking macro (Rasmus Villemoes) Joel Fernandes (Google) (9): rcu/update: Remove useless check for debug_locks rcu: Add support for consolidated-RCU reader checking rcu/sync: Remove custom check for reader-section ipv4: add lockdep condition to fix for_each_entry driver/core: Convert to use built-in RCU list checking workqueue: Convert for_each_wq to use built-in list check x86/pci: Pass lockdep condition to pcm_mmcfg_list iterator acpi: Use built-in RCU list checking for acpi_ioremaps list doc: Update documentation about list_for_each_entry_rcu Documentation/RCU/lockdep.txt | 15 +++++++++++---- Documentation/RCU/whatisRCU.txt | 9 ++++++++- arch/x86/pci/mmconfig-shared.c | 5 +++-- drivers/acpi/osl.c | 6 ++++-- drivers/base/base.h | 1 + drivers/base/core.c | 10 ++++++++++ drivers/base/power/runtime.c | 15 ++++++++++----- include/linux/rcu_sync.h | 5 ++--- include/linux/rculist.h | 28 +++++++++++++++++++++++----- include/linux/rcupdate.h | 7 +++++++ kernel/rcu/Kconfig.debug | 11 +++++++++++ kernel/rcu/sync.c | 22 ---------------------- kernel/rcu/update.c | 20 +++++++++++++++----- kernel/workqueue.c | 10 ++-------- net/ipv4/fib_frontend.c | 3 ++- 15 files changed, 109 insertions(+), 58 deletions(-) --- 2.22.0.510.g264f2c817a-goog