Received: by 2002:ac0:aa62:0:0:0:0:0 with SMTP id w31-v6csp1948526ima; Thu, 25 Oct 2018 07:26:16 -0700 (PDT) X-Google-Smtp-Source: AJdET5eBGOG1E/jlc5McvPTA9gd1sbb03jiUzf7XGncM090GghsOVpz31Nn0/Rn1V8xBWeHpSkdI X-Received: by 2002:a17:902:103:: with SMTP id 3-v6mr1751048plb.58.1540477576856; Thu, 25 Oct 2018 07:26:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1540477576; cv=none; d=google.com; s=arc-20160816; b=HqD969h7/Ky9PKYT1CT6Qw2Dn1O2v4XQ8FDMPUSTNgjOrSaeoMlWlB79xcuZzOB8c9 MS+RlmxrUxcn4tJIj8DGC8dUF+PdFX5lFql3keIsqwrzKAGEathTChQlRlYcpl2ab/Fh kjr/vSeDmfbnhpdosdylK9UZariKavM9FqZZsfH14Is/m7NbDJfnt4h3CP5hqph+9E/6 LioAVryHbfW3xQC6ke3iMQvstru+XbXVu5a8YrzMDiSELL8sG5KgN8HclPRj0mvWna8/ oDQUpTfvF9iO3NvkiqKZmrYZ1jY4y0S9A1f8MrbwWDHyEIGJ4KblhFvRVzpIwJ85VMyM 755A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature; bh=/RrdnM7Tut49okfygOwOCGB323DCfa2QysvIkTcjq0E=; b=iGnDhBHgUqhz0TDTZfQYlBw3Ur40qHOK3fN8FMQ4cjElSwYsNNQI6GsyWfs+RdhDBY kTVQmXWcyARZK1mGDW/IwjyLj6B60933aqmnFS+6lxQrxtm1QzDhzenTYTx/TkT7pY5r wheI4/I0tZGdK3sI6GDbpd+LOQvelDRTurOXTo5zdpP3PASFlgwyuaobcR0aLFIgQigq Ksu5nty9AxeTKXyUFzE83w2gE3k8xBduHtdby7HlPC8cXpSC/mh6IcVJysbQzUR5zg8y SsALC6G0oVZt020quxlTBdOF8T9BzUz4NBT6l1loqpZya6aFZ3AUg6oALI6VTFaQs6+Q J+jw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=WLmf06Ld; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e3-v6si8321213pga.369.2018.10.25.07.25.38; Thu, 25 Oct 2018 07:26:16 -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; dkim=pass header.i=@kernel.org header.s=default header.b=WLmf06Ld; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731197AbeJYWxq (ORCPT + 99 others); Thu, 25 Oct 2018 18:53:46 -0400 Received: from mail.kernel.org ([198.145.29.99]:36348 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731163AbeJYWxo (ORCPT ); Thu, 25 Oct 2018 18:53:44 -0400 Received: from sasha-vm.mshome.net (unknown [167.98.65.38]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 589FE20883; Thu, 25 Oct 2018 14:20:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1540477245; bh=XHpsIHIpyVL7vf9C+lA0UdvojbaiVRRNTLpi5oKumPw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WLmf06LdNfp519sSJRDbaGjI9gLFtXjbmjiSbvbGEls1jtPB2dVZCd0ur3DEY/fh4 Mg9sAysP1gAuBhMNXk7h8JnDRM1qFGu4lrM5Fi6/tqriNXntboP9iexgqpjekXzWuA yLASnPmuU12sZkWXnWFHIsCQR3gVFn0EUB25Z+Q0= From: Sasha Levin To: stable@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Brian Norris , Sasha Levin Subject: [PATCH AUTOSEL 3.18 73/98] mtd: blkdevs: fix potential deadlock + lockdep warnings Date: Thu, 25 Oct 2018 10:18:28 -0400 Message-Id: <20181025141853.214051-73-sashal@kernel.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181025141853.214051-1-sashal@kernel.org> References: <20181025141853.214051-1-sashal@kernel.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Brian Norris [ Upstream commit f3c63795e90f0c6238306883b6c72f14d5355721 ] Commit 073db4a51ee4 ("mtd: fix: avoid race condition when accessing mtd->usecount") fixed a race condition but due to poor ordering of the mutex acquisition, introduced a potential deadlock. The deadlock can occur, for example, when rmmod'ing the m25p80 module, which will delete one or more MTDs, along with any corresponding mtdblock devices. This could potentially race with an acquisition of the block device as follows. -> blktrans_open() -> mutex_lock(&dev->lock); -> mutex_lock(&mtd_table_mutex); -> del_mtd_device() -> mutex_lock(&mtd_table_mutex); -> blktrans_notify_remove() -> del_mtd_blktrans_dev() -> mutex_lock(&dev->lock); This is a classic (potential) ABBA deadlock, which can be fixed by making the A->B ordering consistent everywhere. There was no real purpose to the ordering in the original patch, AFAIR, so this shouldn't be a problem. This ordering was actually already present in del_mtd_blktrans_dev(), for one, where the function tried to ensure that its caller already held mtd_table_mutex before it acquired &dev->lock: if (mutex_trylock(&mtd_table_mutex)) { mutex_unlock(&mtd_table_mutex); BUG(); } So, reverse the ordering of acquisition of &dev->lock and &mtd_table_mutex so we always acquire mtd_table_mutex first. Snippets of the lockdep output follow: # modprobe -r m25p80 [ 53.419251] [ 53.420838] ====================================================== [ 53.427300] [ INFO: possible circular locking dependency detected ] [ 53.433865] 4.3.0-rc6 #96 Not tainted [ 53.437686] ------------------------------------------------------- [ 53.444220] modprobe/372 is trying to acquire lock: [ 53.449320] (&new->lock){+.+...}, at: [] del_mtd_blktrans_dev+0x80/0xdc [ 53.457271] [ 53.457271] but task is already holding lock: [ 53.463372] (mtd_table_mutex){+.+.+.}, at: [] del_mtd_device+0x18/0x100 [ 53.471321] [ 53.471321] which lock already depends on the new lock. [ 53.471321] [ 53.479856] [ 53.479856] the existing dependency chain (in reverse order) is: [ 53.487660] -> #1 (mtd_table_mutex){+.+.+.}: [ 53.492331] [] blktrans_open+0x34/0x1a4 [ 53.497879] [] __blkdev_get+0xc4/0x3b0 [ 53.503364] [] blkdev_get+0x108/0x320 [ 53.508743] [] do_dentry_open+0x218/0x314 [ 53.514496] [] path_openat+0x4c0/0xf9c [ 53.519959] [] do_filp_open+0x5c/0xc0 [ 53.525336] [] do_sys_open+0xfc/0x1cc [ 53.530716] [] ret_fast_syscall+0x0/0x1c [ 53.536375] -> #0 (&new->lock){+.+...}: [ 53.540587] [] mutex_lock_nested+0x38/0x3cc [ 53.546504] [] del_mtd_blktrans_dev+0x80/0xdc [ 53.552606] [] blktrans_notify_remove+0x7c/0x84 [ 53.558891] [] del_mtd_device+0x74/0x100 [ 53.564544] [] del_mtd_partitions+0x80/0xc8 [ 53.570451] [] mtd_device_unregister+0x24/0x48 [ 53.576637] [] spi_drv_remove+0x1c/0x34 [ 53.582207] [] __device_release_driver+0x88/0x114 [ 53.588663] [] device_release_driver+0x20/0x2c [ 53.594843] [] bus_remove_device+0xd8/0x108 [ 53.600748] [] device_del+0x10c/0x210 [ 53.606127] [] device_unregister+0xc/0x20 [ 53.611849] [] __unregister+0x10/0x20 [ 53.617211] [] device_for_each_child+0x50/0x7c [ 53.623387] [] spi_unregister_master+0x58/0x8c [ 53.629578] [] release_nodes+0x15c/0x1c8 [ 53.635223] [] __device_release_driver+0x90/0x114 [ 53.641689] [] driver_detach+0xb4/0xb8 [ 53.647147] [] bus_remove_driver+0x4c/0xa0 [ 53.652970] [] SyS_delete_module+0x11c/0x1e4 [ 53.658976] [] ret_fast_syscall+0x0/0x1c [ 53.664621] [ 53.664621] other info that might help us debug this: [ 53.664621] [ 53.672979] Possible unsafe locking scenario: [ 53.672979] [ 53.679169] CPU0 CPU1 [ 53.683900] ---- ---- [ 53.688633] lock(mtd_table_mutex); [ 53.692383] lock(&new->lock); [ 53.698306] lock(mtd_table_mutex); [ 53.704658] lock(&new->lock); [ 53.707946] [ 53.707946] *** DEADLOCK *** Fixes: 073db4a51ee4 ("mtd: fix: avoid race condition when accessing mtd->usecount") Reported-by: Felipe Balbi Tested-by: Felipe Balbi Signed-off-by: Brian Norris Cc: Signed-off-by: Sasha Levin --- drivers/mtd/mtd_blkdevs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index 3e3aa17ee3bd..6368300f3fbe 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c @@ -195,8 +195,8 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) if (!dev) return -ERESTARTSYS; /* FIXME: busy loop! -arnd*/ - mutex_lock(&dev->lock); mutex_lock(&mtd_table_mutex); + mutex_lock(&dev->lock); if (dev->open) goto unlock; @@ -220,8 +220,8 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) unlock: dev->open++; - mutex_unlock(&mtd_table_mutex); mutex_unlock(&dev->lock); + mutex_unlock(&mtd_table_mutex); blktrans_dev_put(dev); return ret; @@ -231,8 +231,8 @@ static int blktrans_open(struct block_device *bdev, fmode_t mode) error_put: module_put(dev->tr->owner); kref_put(&dev->ref, blktrans_dev_release); - mutex_unlock(&mtd_table_mutex); mutex_unlock(&dev->lock); + mutex_unlock(&mtd_table_mutex); blktrans_dev_put(dev); return ret; } @@ -244,8 +244,8 @@ static void blktrans_release(struct gendisk *disk, fmode_t mode) if (!dev) return; - mutex_lock(&dev->lock); mutex_lock(&mtd_table_mutex); + mutex_lock(&dev->lock); if (--dev->open) goto unlock; @@ -259,8 +259,8 @@ static void blktrans_release(struct gendisk *disk, fmode_t mode) __put_mtd_device(dev->mtd); } unlock: - mutex_unlock(&mtd_table_mutex); mutex_unlock(&dev->lock); + mutex_unlock(&mtd_table_mutex); blktrans_dev_put(dev); } -- 2.17.1