From patchwork Tue Oct 8 12:07:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Stepien, Slawomir (Nokia - PL/Wroclaw)" X-Patchwork-Id: 1173282 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-i2c-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=nokia.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=nokia.onmicrosoft.com header.i=@nokia.onmicrosoft.com header.b="qvEcJhAE"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 46nbhM1pdKz9s4Y for ; Tue, 8 Oct 2019 23:07:47 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730746AbfJHMHq (ORCPT ); Tue, 8 Oct 2019 08:07:46 -0400 Received: from mail-eopbgr30128.outbound.protection.outlook.com ([40.107.3.128]:50190 "EHLO EUR03-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730199AbfJHMHq (ORCPT ); Tue, 8 Oct 2019 08:07:46 -0400 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CBzO51g2Aix20XvV2ikgBsWjQf4juBXZKXiS6s+h4FGuTaUvoYKYZhSBZU15ul4UtvqHhAyAN6Y6ibYaXcElLomvnxDSZ8H0MOZJYvmjTbzWRb7wJSmnmfbht5oMrt+TqOgFJGT17jtzWBR+twoObiZ4VJvIMy+S2E9+3tTyTYJslzFdkQiwhxXpdyZJPP/TzC3IvTenitGhsjjaUoBedhHqOxHKnHT19SPDmXyuxG7nx4O9onPfJ4sXpyR3mUVIsWhqzekYCzE8nNv5Kntz7oVUQr0uyXfXDn/KfHKrk8Z6YdOjrA+jy+w0CnLMRJXu0mQtpyYGsPWI1E8WlYkmGQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fYEiGsIfPxdGFdG02cIfVs2pZDD7LWoTDFJvbAoG34I=; b=SlnW5jSDnQ7F+vWOVNgcJ+enqGBPmrDg5DV6igpiEYyzjw523AtGNAPuErOPEfQKeEx5c2OxEO93dBXeFkYBtXBm6fOwsdN1mwkX0Nb43RHzlVMX2fYTk4hDm9v3bofl1dhr6Py/VYWOTUIhXE3IcfSs/M1rHyPMDo+VOtpPZSLPG75T2FUCKi1B3vTJ9LREPAYk2Ax11jhJUFNglfZqo5/DMvM1e/lw7S5h3ThmymoEnVpd2JZLPuzPo4xBiPXnpN9CXrfcJ+w2vktsuKq9gKMe553MWd/965vUFZPXpjdONWST/OmLa5YiOiYSglX+bLBgbJ9Sm61d1X9dteBb0Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nokia.com; dmarc=pass action=none header.from=nokia.com; dkim=pass header.d=nokia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nokia.onmicrosoft.com; s=selector1-nokia-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fYEiGsIfPxdGFdG02cIfVs2pZDD7LWoTDFJvbAoG34I=; b=qvEcJhAE2OjvyX/k36+odmVnHYmEcpje7fNx8R8Yo9ksGlc/LUYlNC1JJhAlsYl5HF/+eBY3xopV6mdw8VeE4DhlTUhiDiDxpS1mHb5QGlc85xWtCrt5/0t+6agAMAkXdhENYy6FEqFc0TKfiOlqRMluH5tmIx5wZbg0aZ1kvPU= Received: from AM0PR07MB4657.eurprd07.prod.outlook.com (52.135.145.14) by AM0PR07MB5233.eurprd07.prod.outlook.com (20.178.16.91) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2347.15; Tue, 8 Oct 2019 12:07:41 +0000 Received: from AM0PR07MB4657.eurprd07.prod.outlook.com ([fe80::c825:1956:bfa1:fcc9]) by AM0PR07MB4657.eurprd07.prod.outlook.com ([fe80::c825:1956:bfa1:fcc9%7]) with mapi id 15.20.2347.014; Tue, 8 Oct 2019 12:07:41 +0000 From: "Stepien, Slawomir (Nokia - PL/Wroclaw)" To: "wsa@the-dreams.de" , "linux-i2c@vger.kernel.org" CC: "Adamski, Krzysztof (Nokia - PL/Wroclaw)" , "Sverdlin, Alexander (Nokia - DE/Ulm)" , "Lewalski, Jakub (Nokia - PL/Wroclaw)" Subject: [RFCv2] i2c: hold the core_lock for the whole execution of i2c_register_adapter() Thread-Topic: [RFCv2] i2c: hold the core_lock for the whole execution of i2c_register_adapter() Thread-Index: AQHVfdD8sceoYhN0R0CiS8BJensC6Q== Date: Tue, 8 Oct 2019 12:07:41 +0000 Message-ID: <20191008120737.GI20258@sstepien> References: <20181204124514.GD20015@sstepien> In-Reply-To: <20181204124514.GD20015@sstepien> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-clientproxiedby: HE1P191CA0003.EURP191.PROD.OUTLOOK.COM (2603:10a6:3:cf::13) To AM0PR07MB4657.eurprd07.prod.outlook.com (2603:10a6:208:6c::14) x-originating-ip: [131.228.32.167] authentication-results: spf=none (sender IP is ) smtp.mailfrom=slawomir.stepien@nokia.com; x-ms-exchange-messagesentrepresentingtype: 1 x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 12da2350-d60a-4395-e73c-08d74be81e7f x-ms-office365-filtering-ht: Tenant x-ms-traffictypediagnostic: AM0PR07MB5233: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:6430; x-forefront-prvs: 01842C458A x-forefront-antispam-report: SFV:NSPM; SFS:(10019020)(7916004)(4636009)(346002)(366004)(39860400002)(136003)(396003)(376002)(189003)(199004)(76176011)(5660300002)(11346002)(7736002)(25786009)(86362001)(478600001)(2906002)(476003)(66574012)(81166006)(8936002)(81156014)(305945005)(256004)(1076003)(446003)(486006)(14454004)(8676002)(52116002)(14444005)(6436002)(6116002)(107886003)(186003)(6512007)(3846002)(9686003)(71200400001)(66946007)(71190400001)(66476007)(99286004)(66066001)(6486002)(6506007)(33716001)(386003)(110136005)(26005)(33656002)(64756008)(102836004)(66556008)(54906003)(66446008)(4326008)(2501003)(316002); DIR:OUT; SFP:1102; SCL:1; SRVR:AM0PR07MB5233; H:AM0PR07MB4657.eurprd07.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; MX:1; A:1; received-spf: None (protection.outlook.com: nokia.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: VULihBV0UR9AiALz1itwUdBM+Zrq3j42F0mYVIC5Wabs8h92exwavdvkpPuhi1r+YVkLieTVr88BdxeWGdDI2efGHwIqaw0uLh97PmfHLvbTIx/IZ8LDevG/ro/g1yIfqOWQheCzr9sK9N+M3Lc36Z5WOWLGqHlN39IqHq1AbZn2zarWVQ7daBhBao/IV1uRRTM5KbBz8NAl93k+7WRsMFTHpu/rFVWt3gp+lU4J3GO85iD6eK2II3P3hH/A4arwF5ZxsNdFf1+QZwsdeN49JB4y3mkp15P8LeGgPVFzLeLrXZKm8zN83Gda0ZHHM7cMLgMUQodsbNpR3gp2EPq8Ck/NzCajJQp2ChRFcvAjPTKGJZwEGBtvEeQuRiVuvWQj1qFKkpNDd5txMJ3QPqjOsCPy+spp0T/aUspafEqy7OI= Content-ID: <47068B7AB27B5648897FF71E06651797@eurprd07.prod.outlook.com> MIME-Version: 1.0 X-OriginatorOrg: nokia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 12da2350-d60a-4395-e73c-08d74be81e7f X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Oct 2019 12:07:41.3738 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 5d471751-9675-428d-917b-70f44f9630b0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: tWS3qCTfuRSqGFGuuxG1pyYo7YMX4qC7wFBw4FoAfZ0QvtSGCom0kUohLsOZmuAfRkhxY63KffT5+FFhipHP1i8gSZQApYqr2bzpA4vAyRU= X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR07MB5233 Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org There is a race condition between the i2c_get_adapter() and the i2c_add_adapter() if this mutex isn't hold for the whole execution of i2c_register_adapter(). If the mutex isn't locked, it is possible to find idr that points to adapter that hasn't been registered yet (i.e. it's kobj.state_initialized is still false), which will end up with warning message: "... is not initialized, yet kobject_get() is being called." This patch will change how the locking is arranged around i2c_register_adapter() call and will prevent such situations. The part of the i2c_register_adapter() that do not need to be under the lock has been moved to a new function i2c_process_adapter. Signed-off-by: Sławomir Stępień --- v1 -> v2: * added return 0; just before out_reg label. --- drivers/i2c/i2c-core-base.c | 63 +++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index 5f6a4985f2bc..cf9c5d18a24c 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -1352,6 +1352,23 @@ static int i2c_register_adapter(struct i2c_adapter *adap) dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); + return 0; + +out_reg: + init_completion(&adap->dev_released); + device_unregister(&adap->dev); + wait_for_completion(&adap->dev_released); +out_list: + idr_remove(&i2c_adapter_idr, adap->nr); + return res; +} + +static void i2c_process_adapter(struct i2c_adapter *adap) +{ +#ifdef CONFIG_I2C_COMPAT + int res; +#endif + pm_runtime_no_callbacks(&adap->dev); pm_suspend_ignore_children(&adap->dev, true); pm_runtime_enable(&adap->dev); @@ -1378,18 +1395,6 @@ static int i2c_register_adapter(struct i2c_adapter *adap) mutex_lock(&core_lock); bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter); mutex_unlock(&core_lock); - - return 0; - -out_reg: - init_completion(&adap->dev_released); - device_unregister(&adap->dev); - wait_for_completion(&adap->dev_released); -out_list: - mutex_lock(&core_lock); - idr_remove(&i2c_adapter_idr, adap->nr); - mutex_unlock(&core_lock); - return res; } /** @@ -1401,15 +1406,24 @@ static int i2c_register_adapter(struct i2c_adapter *adap) */ static int __i2c_add_numbered_adapter(struct i2c_adapter *adap) { - int id; + int id, ret; mutex_lock(&core_lock); id = idr_alloc(&i2c_adapter_idr, adap, adap->nr, adap->nr + 1, GFP_KERNEL); - mutex_unlock(&core_lock); - if (WARN(id < 0, "couldn't get idr")) + if (WARN(id < 0, "couldn't get idr")) { + mutex_unlock(&core_lock); return id == -ENOSPC ? -EBUSY : id; + } + + ret = i2c_register_adapter(adap); + mutex_unlock(&core_lock); + + if (ret < 0) + return ret; - return i2c_register_adapter(adap); + i2c_process_adapter(adap); + + return 0; } /** @@ -1429,7 +1443,7 @@ static int __i2c_add_numbered_adapter(struct i2c_adapter *adap) int i2c_add_adapter(struct i2c_adapter *adapter) { struct device *dev = &adapter->dev; - int id; + int id, ret; if (dev->of_node) { id = of_alias_get_id(dev->of_node, "i2c"); @@ -1442,13 +1456,22 @@ int i2c_add_adapter(struct i2c_adapter *adapter) mutex_lock(&core_lock); id = idr_alloc(&i2c_adapter_idr, adapter, __i2c_first_dynamic_bus_num, 0, GFP_KERNEL); - mutex_unlock(&core_lock); - if (WARN(id < 0, "couldn't get idr")) + if (WARN(id < 0, "couldn't get idr")) { + mutex_unlock(&core_lock); return id; + } adapter->nr = id; - return i2c_register_adapter(adapter); + ret = i2c_register_adapter(adapter); + mutex_unlock(&core_lock); + + if (ret < 0) + return ret; + + i2c_process_adapter(adapter); + + return 0; } EXPORT_SYMBOL(i2c_add_adapter);