[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1355793187-2638-3-git-send-email-hannes@stressinduktion.org>
Date: Tue, 18 Dec 2012 02:13:05 +0100
From: Hannes Frederic Sowa <hannes@...essinduktion.org>
To: linux-kernel@...r.kernel.org
Cc: npiggin@...nel.dk,
Hannes Frederic Sowa <hannes@...essinduktion.org>
Subject: [PATCH v2 2/4] brd: check for open partitions when BLKFLSBUFing a ram disk
Users of partitions on ram disks could accidentally flush the block
device with ioctl(BLKFLSBUF) while it is in use. This patch prevents
this from happening.
This patch also adds a call to rescan_partitions after BLKFLSBUFing,
for which a EXPORT_SYMBOL_GPL statement was needed. Otherwise some kind
of use-after-free could happen.
After this change BLKFLSBUFing on partitions of a ram disk is never
possible.
Cc: Nick Piggin <npiggin@...nel.dk>
Signed-off-by: Hannes Frederic Sowa <hannes@...essinduktion.org>
---
block/partition-generic.c | 1 +
drivers/block/brd.c | 20 +++++++++++++++++---
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/block/partition-generic.c b/block/partition-generic.c
index f1d1451..cd7bc10 100644
--- a/block/partition-generic.c
+++ b/block/partition-generic.c
@@ -528,6 +528,7 @@ rescan:
kfree(state);
return 0;
}
+EXPORT_SYMBOL_GPL(rescan_partitions);
int invalidate_partitions(struct gendisk *disk, struct block_device *bdev)
{
diff --git a/drivers/block/brd.c b/drivers/block/brd.c
index 70ad8dc..80dd094 100644
--- a/drivers/block/brd.c
+++ b/drivers/block/brd.c
@@ -385,6 +385,13 @@ static int brd_direct_access(struct block_device *bdev, sector_t sector,
}
#endif
+static int brd_blkdev_in_use(struct block_device *bdev)
+{
+ lockdep_assert_held(&bdev->bd_mutex);
+ return bdev->bd_part_count > 0
+ || bdev->bd_openers > 1;
+}
+
static int brd_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
@@ -399,9 +406,15 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode,
* release and destroy the ramdisk data.
*/
mutex_lock(&brd_mutex);
+ if (bdget_disk(brd->brd_disk, 0) != bdev) {
+ error = -EBUSY;
+ goto out;
+ }
mutex_lock(&bdev->bd_mutex);
- error = -EBUSY;
- if (bdev->bd_openers <= 1) {
+ error = brd_blkdev_in_use(bdev);
+ if (error) {
+ error = -EBUSY;
+ } else {
/*
* Kill the cache first, so it isn't written back to the
* device.
@@ -411,9 +424,10 @@ static int brd_ioctl(struct block_device *bdev, fmode_t mode,
*/
kill_bdev(bdev);
brd_free_pages(brd);
- error = 0;
+ error = rescan_partitions(brd->brd_disk, bdev);
}
mutex_unlock(&bdev->bd_mutex);
+out:
mutex_unlock(&brd_mutex);
return error;
--
1.8.0.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists