From: Jan Kara <jack@suse.cz>
To: Jens Axboe <axboe@kernel.dk>
Cc: <linux-block@vger.kernel.org>, Hou Tao <houtao1@huawei.com>,
Jan Kara <jack@suse.cz>
Subject: [PATCH 4/6] genhd: Fix use after free in __blkdev_get()
Date: Mon, 26 Feb 2018 13:01:40 +0100 [thread overview]
Message-ID: <20180226120142.25786-5-jack@suse.cz> (raw)
In-Reply-To: <20180226120142.25786-1-jack@suse.cz>
When two blkdev_open() calls race with device removal and recreation,
__blkdev_get() can use looked up gendisk after it is freed:
CPU0 CPU1 CPU2
del_gendisk(disk);
bdev_unhash_inode(inode);
blkdev_open() blkdev_open()
bdev = bd_acquire(inode);
- creates and returns new inode
bdev = bd_acquire(inode);
- returns the same inode
__blkdev_get(devt) __blkdev_get(devt)
disk = get_gendisk(devt);
- got structure of device going away
<finish device removal>
<new device gets
created under the same
device number>
disk = get_gendisk(devt);
- got new device structure
if (!bdev->bd_openers) {
does the first open
}
if (!bdev->bd_openers)
- false
} else {
put_disk_and_module(disk)
- remember this was old device - this was last ref and disk is
now freed
}
disk_unblock_events(disk); -> oops
Fix the problem by making sure we drop reference to disk in
__blkdev_get() only after we are really done with it.
Reported-by: Hou Tao <houtao1@huawei.com>
Tested-by: Hou Tao <houtao1@huawei.com>
Signed-off-by: Jan Kara <jack@suse.cz>
---
fs/block_dev.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 1dbbf847911a..fe41a76769fa 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1409,6 +1409,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
int ret;
int partno;
int perm = 0;
+ bool first_open = false;
if (mode & FMODE_READ)
perm |= MAY_READ;
@@ -1435,6 +1436,7 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
disk_block_events(disk);
mutex_lock_nested(&bdev->bd_mutex, for_part);
if (!bdev->bd_openers) {
+ first_open = true;
bdev->bd_disk = disk;
bdev->bd_queue = disk->queue;
bdev->bd_contains = bdev;
@@ -1520,14 +1522,15 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
if (ret)
goto out_unlock_bdev;
}
- /* only one opener holds refs to the module and disk */
- put_disk_and_module(disk);
}
bdev->bd_openers++;
if (for_part)
bdev->bd_part_count++;
mutex_unlock(&bdev->bd_mutex);
disk_unblock_events(disk);
+ /* only one opener holds refs to the module and disk */
+ if (!first_open)
+ put_disk_and_module(disk);
return 0;
out_clear:
--
2.13.6
next prev parent reply other threads:[~2018-02-26 12:01 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-02-26 12:01 [PATCH 0/6 v2] block: Fix races in bdev - gendisk handling Jan Kara
2018-02-26 12:01 ` [PATCH 1/6] genhd: Fix leaked module reference for NVME devices Jan Kara
2018-02-27 0:09 ` Christoph Hellwig
2018-02-26 12:01 ` [PATCH 2/6] genhd: Rename get_disk() to get_disk_and_module() Jan Kara
2018-02-26 12:01 ` [PATCH 3/6] genhd: Add helper put_disk_and_module() Jan Kara
2018-02-26 12:01 ` Jan Kara [this message]
2018-02-26 12:01 ` [PATCH 5/6] genhd: Fix BUG in blkdev_open() Jan Kara
2018-02-26 12:01 ` [PATCH 6/6] blockdev: Avoid two active bdev inodes for one device Jan Kara
2018-02-26 16:04 ` [PATCH 0/6 v2] block: Fix races in bdev - gendisk handling Jens Axboe
2018-02-26 16:43 ` Jan Kara
2018-02-26 16:49 ` Jens Axboe
-- strict thread matches above, loose matches on Subject: below --
2018-02-06 16:05 [PATCH 0/6] " Jan Kara
2018-02-06 16:05 ` [PATCH 4/6] genhd: Fix use after free in __blkdev_get() Jan Kara
2018-02-13 2:11 ` Hou Tao
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180226120142.25786-5-jack@suse.cz \
--to=jack@suse.cz \
--cc=axboe@kernel.dk \
--cc=houtao1@huawei.com \
--cc=linux-block@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.