Received: by 2002:ac0:8c9a:0:0:0:0:0 with SMTP id r26csp306056ima; Thu, 31 Jan 2019 17:12:39 -0800 (PST) X-Google-Smtp-Source: ALg8bN5CfJo6karSyf6qhPOCxd8oABNP6vjF+1bYLn64w9G2ZVZ6LNMMcn2Y0MaBIQIh1C6kizMu X-Received: by 2002:a62:75d1:: with SMTP id q200mr37074296pfc.254.1548983559545; Thu, 31 Jan 2019 17:12:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1548983559; cv=none; d=google.com; s=arc-20160816; b=AKeIUCyNsTkY7Cs1Yo4Ee+lf5UDR4cdtKKogizfHyIPYGHP9PaRrES/lrRlqoEGnM3 4BdgzKuY902N56sZ4cSeUSrgekKCff2r4RcMOU5J0N7DyOUgjMwtflK9HqIB2Ik2CgII SPHH9Xgpi9ltOkk3kc+dqSoT+vdkrrO4B7RoMHVhVlffRA8DfY32Fw5KqHKEzvIvRZFs RlAzCWMSXw3sa8UxZcOJRunH0mYvEktWh8MhhnJZzdMRXZJrGkdWqRbwUPP+Xo08Yhqd WHalb3kzqno80YLDg0Vfqi+NHox/PsIaMqenGsYb9WwORIQKFkF0Yh71Q4x+xXVhSu3C 3myg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=vwQZo8dg7b6nBT7t1292R78sZysh4vz/nYl8bM7bcWs=; b=wQAxCgfy95sMA7rIjp2Nd3TYNbQ0DUP68SNAJSfFMGBaj0+eo4IM3C49mkhNJJFWmR jKjHyMMzi19eIu2HsWw6DFzLcxAVDipHKB0boWJ5nS7CNEm/PbdK7cLX0O03o4b9ql1a DVXmKAzy3zffI8Y7R0cQ6RpRnTEZLq6uK2FYk+HUD43vJw2aJQU+DzhKzuri3aUfbluT TnF+pVl3ZcqA9AWeo6ChCo3cVsYPiGVLXBVZqeHNwB5TqpBHNKDqoreW2ARkGnb4JvYN /WLWWz+kp7LJrw998Llqb+v64HlXeFb+AkJlSjKeaUYtLe+ywAq3Kp1d8GLMDLD4KFST 0zjQ== 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 go3si6043024plb.97.2019.01.31.17.12.24; Thu, 31 Jan 2019 17:12:39 -0800 (PST) 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 S1727960AbfBABEF (ORCPT + 99 others); Thu, 31 Jan 2019 20:04:05 -0500 Received: from cloudserver094114.home.pl ([79.96.170.134]:49948 "EHLO cloudserver094114.home.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727699AbfBABEE (ORCPT ); Thu, 31 Jan 2019 20:04:04 -0500 Received: from 79.184.255.169.ipv4.supernova.orange.pl (79.184.255.169) (HELO aspire.rjw.lan) by serwer1319399.home.pl (79.96.170.134) with SMTP (IdeaSmtpServer 0.83.183) id 52647f3649c24aeb; Fri, 1 Feb 2019 02:04:02 +0100 From: "Rafael J. Wysocki" To: Greg Kroah-Hartman Cc: LKML , Linux PM , Ulf Hansson , Daniel Vetter , Lukas Wunner , Andrzej Hajda , Russell King - ARM Linux , Lucas Stach , Linus Walleij , Thierry Reding , Laurent Pinchart , Marek Szyprowski , Joerg Roedel Subject: [PATCH v2 2/9] driver core: Avoid careless re-use of existing device links Date: Fri, 01 Feb 2019 01:46:54 +0100 Message-ID: <2222273.ydJmd408XJ@aspire.rjw.lan> In-Reply-To: <1952449.TVsm6CJCTy@aspire.rjw.lan> References: <1952449.TVsm6CJCTy@aspire.rjw.lan> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rafael J. Wysocki After commit ead18c23c263 ("driver core: Introduce device links reference counting"), if there is a link between the given supplier and the given consumer already, device_link_add() will refcount it and return it unconditionally. However, if the flags passed to it on the second (or any subsequent) attempt to create a device link between the same consumer-supplier pair are not compatible with the existing link's flags, that is incorrect. First off, if the existing link is stateless and the next caller of device_link_add() for the same consumer-supplier pair wants a stateful one, or the other way around, the existing link cannot be returned, because it will not match the expected behavior, so make device_link_add() dump the stack and return NULL in that case. Moreover, if the DL_FLAG_AUTOREMOVE_CONSUMER flag is passed to device_link_add(), its caller will expect its reference to the link to be dropped automatically on consumer driver removal, which will not happen if that flag is not set in the link's flags (and analogously for DL_FLAG_AUTOREMOVE_SUPPLIER). For this reason, make device_link_add() update the existing link's flags accordingly before returning it to the caller. Fixes: ead18c23c263 ("driver core: Introduce device links reference counting") Signed-off-by: Rafael J. Wysocki --- drivers/base/core.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) Index: linux-pm/drivers/base/core.c =================================================================== --- linux-pm.orig/drivers/base/core.c +++ linux-pm/drivers/base/core.c @@ -221,12 +221,29 @@ struct device_link *device_link_add(stru goto out; } - list_for_each_entry(link, &supplier->links.consumers, s_node) - if (link->consumer == consumer) { - kref_get(&link->kref); + list_for_each_entry(link, &supplier->links.consumers, s_node) { + if (link->consumer != consumer) + continue; + + /* + * Don't return a stateless link if the caller wants a stateful + * one and vice versa. + */ + if (WARN_ON((flags & DL_FLAG_STATELESS) != (link->flags & DL_FLAG_STATELESS))) { + link = NULL; goto out; } + if (flags & DL_FLAG_AUTOREMOVE_CONSUMER) + link->flags |= DL_FLAG_AUTOREMOVE_CONSUMER; + + if (flags & DL_FLAG_AUTOREMOVE_SUPPLIER) + link->flags |= DL_FLAG_AUTOREMOVE_SUPPLIER; + + kref_get(&link->kref); + goto out; + } + link = kzalloc(sizeof(*link), GFP_KERNEL); if (!link) goto out;