Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp909394ybl; Wed, 14 Aug 2019 07:50:10 -0700 (PDT) X-Google-Smtp-Source: APXvYqzyR9JQ4rcrCOXfInXJ5qUy34uRQ8lI8ytwhCer1izv5JQBv0Xey/gyGf9he3nnxm9FLChZ X-Received: by 2002:a63:b10f:: with SMTP id r15mr38705418pgf.230.1565794210056; Wed, 14 Aug 2019 07:50:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565794210; cv=none; d=google.com; s=arc-20160816; b=zrZY7md3XYV7Fi6a6dU96EBIW3qBLnQjn8h9GGUAIOhjXBo83nT+Ft473r+E3yhEco iekFJoyaN9sc0u5dipxMNmiR4QK5SOgMntTscqC6He0mf/U7WEySKgnsRG0owU8PQQb+ y+KcA006FTOM8iWQCtZ9ix+qmVkZj5pfBr8Kbkpvs7AyOLx21k4qubvCcOqqimGatC3e GP4Sh/05hmjJSnSwtbxDMbANxo9sugNWMw5Qi81ZSlrxz04dSKCycOOyqDmI88quDj6b /40WFvN8d1JWR1iZ6d4chDSn2QniPbWdWwivRBdFNx+xMOhLiL68cHesltHdwIk/lryZ mWIQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:content-transfer-encoding :content-language:accept-language:in-reply-to:references:message-id :date:thread-index:thread-topic:subject:cc:to:from:ironport-sdr :ironport-sdr; bh=ng55nrcjLJjMPX/6vfrTQBub3EAeRmls9z2aoB0itgo=; b=weZD5Z2pAH+tVBrYIkxtjMD9xT5xelz2mf41dMLH2MYdbmX4FPXMAUpb0FCmMI5Z7D 7oOP5K+t45bw3FjQzocbdDH9caadoRqJTbIOSnd0u3kXJyw8nfwEGb6eJppTkLvamgML KtGZYK9A4tMTLaGfhPGwrCgl7dDwBHXAJ8oZe0A35O5TjNj3vWaxx8gSNYBDPMxoa2o7 X62ORkjVokUpesIRDunVoY0GaYqvVrZpV0YUUrFMnzSpwaFgCHgtnPUo2+GJO51m6K9v BVt51PjajY6l0qUzqkfqX2kUh3woahfvT/SQb9jZPAuR4YfnETq4eAx6F0d5uufsI5yi F2pg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z20si48633plo.159.2019.08.14.07.49.54; Wed, 14 Aug 2019 07:50:10 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728053AbfHNOsn convert rfc822-to-8bit (ORCPT + 99 others); Wed, 14 Aug 2019 10:48:43 -0400 Received: from esa3.mentor.iphmx.com ([68.232.137.180]:3215 "EHLO esa3.mentor.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725955AbfHNOsm (ORCPT ); Wed, 14 Aug 2019 10:48:42 -0400 IronPort-SDR: Ob59t+9w4lRE1kWR5UzVGEd85CtqqVHAWPphIDI/ltJpNgfsJnthWDUYxbHvaEInT7gojXXZ/Q NtsvuNwrDdEMEhXw1fL1woklX3IZoeGyBiybeEZzIIHJV2AHzviw7E2Tt8ScGK2uYnB/oa7D4Y 8RHZwi2795dn/YfQvbKS5mAzODZ6qF0tuzLf+PLkPPiLcs5UxhObzkv6s0e+wFgFBhqU3SSbeS XQIQKKv947myM5uD7lbp4jQZS8V9nabtZfRRSNBkHxuEc+hhQbJMKDw4+qcEt8nAg9hiG/Dw3B QVY= X-IronPort-AV: E=Sophos;i="5.64,385,1559548800"; d="scan'208";a="40450613" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa3.mentor.iphmx.com with ESMTP; 14 Aug 2019 06:48:30 -0800 IronPort-SDR: jMbxt+ASILuBqBmL8+IglLxg6Ajyl0a0rhfMqOHnnYTPuLghprJPi/pPceLenN6Mh+luI9XYdv 6fEFabw8YQNR6aEarhIaQdpByZWBVtFK8SlSQ8E+LImhDGyOT3+BUKWr4QpS7B0uTl5Iv7+S8q /tH4J3QKulCM14bsFdlTLDU03WVD2By40ht0m414djYBrmeuQDOXaX2sWODcza0eneex4Py9Qd fahKV16LiZGJCkS+aCiPmFsYmHGAICGCGE6nhHkYCCJxRqe9ZOXOoEXgaxY2iN6HzdiXp7pZtI z0s= From: "Schmid, Carsten" To: Linus Torvalds , Wei Yang CC: "bp@suse.de" , "dan.j.williams@intel.com" , "mingo@kernel.org" , "dave.hansen@linux.intel.com" , "linux-kernel@vger.kernel.org" , "bhelgaas@google.com" , "osalvador@suse.de" , "rdunlap@infradead.org" , "richardw.yang@linux.intel.com" , "gregkh@linuxfoundation.org" Subject: [PATCH v2] kernel/resource.c: invalidate parent when freed resource has childs Thread-Topic: [PATCH v2] kernel/resource.c: invalidate parent when freed resource has childs Thread-Index: AQHVUq5kcb5Ex7JpNUSktSjVjdFuew== Date: Wed, 14 Aug 2019 14:48:24 +0000 Message-ID: <1565794104204.54092@mentor.com> References: <1565278859475.1962@mentor.com> <1565358624103.3694@mentor.com> <20190809223831.fk4uyrzscr366syr@master>, In-Reply-To: Accept-Language: de-DE, en-IE, en-US Content-Language: de-DE X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [137.202.0.90] Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When a resource is freed and has children, the childrens are left without any hint that their parent is no more valid. This caused at least one use-after-free in the xhci-hcd using ext-caps driver when platform code released platform devices. In such case, warn and release all resources beyond. Signed-off-by: Carsten Schmid --- v2: - release everything below the released resource, not only one child; re-using __release_child_resources (Inspired by Linus Torvalds outline) - warn only once (According to Linus Torvalds outline) - Keep parent and child name in warning message (eases hunting for the involved parties) --- kernel/resource.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/kernel/resource.c b/kernel/resource.c index c3cc6d85ec52..eb48d793aa74 100644 --- a/kernel/resource.c +++ b/kernel/resource.c @@ -239,7 +239,7 @@ static int __release_resource(struct resource *old, bool release_child) return -EINVAL; } -static void __release_child_resources(struct resource *r) +static void __release_child_resources(struct resource *r, bool warn) { struct resource *tmp, *p; resource_size_t size; @@ -252,9 +252,10 @@ static void __release_child_resources(struct resource *r) tmp->parent = NULL; tmp->sibling = NULL; - __release_child_resources(tmp); + __release_child_resources(tmp, warn); - printk(KERN_DEBUG "release child resource %pR\n", tmp); + if (warn) + printk(KERN_DEBUG "release child resource %pR\n", tmp); /* need to restore size, and keep flags */ size = resource_size(tmp); tmp->start = 0; @@ -265,7 +266,7 @@ static void __release_child_resources(struct resource *r) void release_child_resources(struct resource *r) { write_lock(&resource_lock); - __release_child_resources(r); + __release_child_resources(r, true); write_unlock(&resource_lock); } @@ -1172,7 +1173,20 @@ EXPORT_SYMBOL(__request_region); * @n: resource region size * * The described resource region must match a currently busy region. + * If the region has children they are released too. */ +static void check_children(struct resource *parent) +{ + if (parent->child) { + /* warn and release all children */ + WARN_ONCE(1, "%s: %s has child %s, release all children\n", + __func__, parent->name, parent->child->name); + write_lock(&resource_lock); + __release_child_resources(parent, false); + write_unlock(&resource_lock); + } +} + void __release_region(struct resource *parent, resource_size_t start, resource_size_t n) { @@ -1200,6 +1214,10 @@ void __release_region(struct resource *parent, resource_size_t start, write_unlock(&resource_lock); if (res->flags & IORESOURCE_MUXED) wake_up(&muxed_resource_wait); + + /* You should'nt release a resource that has children */ + check_children(res); + free_resource(res); return; } -- 2.17.1