All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro()
@ 2018-01-11 13:09 Ilya Dryomov
  2018-01-11 13:09 ` [PATCH v3 1/2] block: fail op_is_write() requests to read-only partitions Ilya Dryomov
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Ilya Dryomov @ 2018-01-11 13:09 UTC (permalink / raw)
  To: linux-block
  Cc: Jens Axboe, Christoph Hellwig, Tejun Heo, David Disseldorp,
	Sagi Grimberg

Hello,

I was doing some cleanup work on rbd BLKROSET handler and discovered
that we ignore partition rw/ro setting (hd_struct->policy) for pretty
much everything but straight writes.

David (CCed) has blktests patches standing by.

(Another aspect of this is that we don't enforce open(2) mode.  Tejun
took a stab at this a few years ago, but his patch had to be reverted:

  75f1dc0d076d ("block: check bdev_read_only() from blkdev_get()")
  e51900f7d38c ("block: revert block_dev read-only check")

It is a separate issue and refusing writes to read-only devices is
obviously more important, but perhaps it's time to revisit that as
well?)

v2 -> v3:
- lookup part only once; combine read-only check with existing
  should_fail_request check

v1 -> v2:
- added unlikely() per Sagi's suggestion

Thanks,

                Ilya


Ilya Dryomov (2):
  block: fail op_is_write() requests to read-only partitions
  block: add bdev_read_only() checks to common helpers

 block/blk-core.c | 56 ++++++++++++++++++++++++++++++++++++++------------------
 block/blk-lib.c  | 12 ++++++++++++
 2 files changed, 50 insertions(+), 18 deletions(-)

-- 
2.4.3

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v3 1/2] block: fail op_is_write() requests to read-only partitions
  2018-01-11 13:09 [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro() Ilya Dryomov
@ 2018-01-11 13:09 ` Ilya Dryomov
  2018-01-14  9:35   ` Sagi Grimberg
  2018-01-11 13:09 ` [PATCH v3 2/2] block: add bdev_read_only() checks to common helpers Ilya Dryomov
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Ilya Dryomov @ 2018-01-11 13:09 UTC (permalink / raw)
  To: linux-block
  Cc: Jens Axboe, Christoph Hellwig, Tejun Heo, David Disseldorp,
	Sagi Grimberg

Regular block device writes go through blkdev_write_iter(), which does
bdev_read_only(), while zeroout/discard/etc requests are never checked,
both userspace- and kernel-triggered.  Add a generic catch-all check to
generic_make_request_checks() to actually enforce ioctl(BLKROSET) and
set_disk_ro(), which is used by quite a few drivers for things like
snapshots, read-only backing files/images, etc.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 block/blk-core.c | 56 ++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 38 insertions(+), 18 deletions(-)

diff --git a/block/blk-core.c b/block/blk-core.c
index f843ae4f858d..44a6dfe47ae1 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -2062,6 +2062,21 @@ static inline bool should_fail_request(struct hd_struct *part,
 
 #endif /* CONFIG_FAIL_MAKE_REQUEST */
 
+static inline bool bio_check_ro(struct bio *bio, struct hd_struct *part)
+{
+	if (part->policy && op_is_write(bio_op(bio))) {
+		char b[BDEVNAME_SIZE];
+
+		printk(KERN_ERR
+		       "generic_make_request: Trying to write "
+			"to read-only block-device %s (partno %d)\n",
+			bio_devname(bio, b), part->partno);
+		return true;
+	}
+
+	return false;
+}
+
 /*
  * Remap block n of partition p to block n+start(p) of the disk.
  */
@@ -2070,27 +2085,28 @@ static inline int blk_partition_remap(struct bio *bio)
 	struct hd_struct *p;
 	int ret = 0;
 
+	rcu_read_lock();
+	p = __disk_get_part(bio->bi_disk, bio->bi_partno);
+	if (unlikely(!p || should_fail_request(p, bio->bi_iter.bi_size) ||
+		     bio_check_ro(bio, p))) {
+		ret = -EIO;
+		goto out;
+	}
+
 	/*
 	 * Zone reset does not include bi_size so bio_sectors() is always 0.
 	 * Include a test for the reset op code and perform the remap if needed.
 	 */
-	if (!bio->bi_partno ||
-	    (!bio_sectors(bio) && bio_op(bio) != REQ_OP_ZONE_RESET))
-		return 0;
+	if (!bio_sectors(bio) && bio_op(bio) != REQ_OP_ZONE_RESET)
+		goto out;
 
-	rcu_read_lock();
-	p = __disk_get_part(bio->bi_disk, bio->bi_partno);
-	if (likely(p && !should_fail_request(p, bio->bi_iter.bi_size))) {
-		bio->bi_iter.bi_sector += p->start_sect;
-		bio->bi_partno = 0;
-		trace_block_bio_remap(bio->bi_disk->queue, bio, part_devt(p),
-				bio->bi_iter.bi_sector - p->start_sect);
-	} else {
-		printk("%s: fail for partition %d\n", __func__, bio->bi_partno);
-		ret = -EIO;
-	}
-	rcu_read_unlock();
+	bio->bi_iter.bi_sector += p->start_sect;
+	bio->bi_partno = 0;
+	trace_block_bio_remap(bio->bi_disk->queue, bio, part_devt(p),
+			      bio->bi_iter.bi_sector - p->start_sect);
 
+out:
+	rcu_read_unlock();
 	return ret;
 }
 
@@ -2149,15 +2165,19 @@ generic_make_request_checks(struct bio *bio)
 	 * For a REQ_NOWAIT based request, return -EOPNOTSUPP
 	 * if queue is not a request based queue.
 	 */
-
 	if ((bio->bi_opf & REQ_NOWAIT) && !queue_is_rq_based(q))
 		goto not_supported;
 
 	if (should_fail_request(&bio->bi_disk->part0, bio->bi_iter.bi_size))
 		goto end_io;
 
-	if (blk_partition_remap(bio))
-		goto end_io;
+	if (!bio->bi_partno) {
+		if (unlikely(bio_check_ro(bio, &bio->bi_disk->part0)))
+			goto end_io;
+	} else {
+		if (blk_partition_remap(bio))
+			goto end_io;
+	}
 
 	if (bio_check_eod(bio, nr_sectors))
 		goto end_io;
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v3 2/2] block: add bdev_read_only() checks to common helpers
  2018-01-11 13:09 [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro() Ilya Dryomov
  2018-01-11 13:09 ` [PATCH v3 1/2] block: fail op_is_write() requests to read-only partitions Ilya Dryomov
@ 2018-01-11 13:09 ` Ilya Dryomov
  2018-01-14  9:35   ` Sagi Grimberg
  2018-01-18 11:16 ` [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro() Ilya Dryomov
  2018-01-18 19:57 ` Jens Axboe
  3 siblings, 1 reply; 7+ messages in thread
From: Ilya Dryomov @ 2018-01-11 13:09 UTC (permalink / raw)
  To: linux-block
  Cc: Jens Axboe, Christoph Hellwig, Tejun Heo, David Disseldorp,
	Sagi Grimberg

Similar to blkdev_write_iter(), return -EPERM if the partition is
read-only.  This covers ioctl(), fallocate() and most in-kernel users
but isn't meant to be exhaustive -- everything else will be caught in
generic_make_request_checks(), fail with -EIO and can be fixed later.

Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
---
 block/blk-lib.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/block/blk-lib.c b/block/blk-lib.c
index 2bc544ce3d2e..a676084d4740 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -37,6 +37,9 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
 	if (!q)
 		return -ENXIO;
 
+	if (bdev_read_only(bdev))
+		return -EPERM;
+
 	if (flags & BLKDEV_DISCARD_SECURE) {
 		if (!blk_queue_secure_erase(q))
 			return -EOPNOTSUPP;
@@ -156,6 +159,9 @@ static int __blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
 	if (!q)
 		return -ENXIO;
 
+	if (bdev_read_only(bdev))
+		return -EPERM;
+
 	bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
 	if ((sector | nr_sects) & bs_mask)
 		return -EINVAL;
@@ -233,6 +239,9 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev,
 	if (!q)
 		return -ENXIO;
 
+	if (bdev_read_only(bdev))
+		return -EPERM;
+
 	/* Ensure that max_write_zeroes_sectors doesn't overflow bi_size */
 	max_write_zeroes_sectors = bdev_write_zeroes_sectors(bdev);
 
@@ -287,6 +296,9 @@ static int __blkdev_issue_zero_pages(struct block_device *bdev,
 	if (!q)
 		return -ENXIO;
 
+	if (bdev_read_only(bdev))
+		return -EPERM;
+
 	while (nr_sects != 0) {
 		bio = next_bio(bio, __blkdev_sectors_to_bio_pages(nr_sects),
 			       gfp_mask);
-- 
2.4.3

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 1/2] block: fail op_is_write() requests to read-only partitions
  2018-01-11 13:09 ` [PATCH v3 1/2] block: fail op_is_write() requests to read-only partitions Ilya Dryomov
@ 2018-01-14  9:35   ` Sagi Grimberg
  0 siblings, 0 replies; 7+ messages in thread
From: Sagi Grimberg @ 2018-01-14  9:35 UTC (permalink / raw)
  To: Ilya Dryomov, linux-block
  Cc: Jens Axboe, Christoph Hellwig, Tejun Heo, David Disseldorp

Reviewed-by: Sagi Grimberg <sagi@grimberg.me>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 2/2] block: add bdev_read_only() checks to common helpers
  2018-01-11 13:09 ` [PATCH v3 2/2] block: add bdev_read_only() checks to common helpers Ilya Dryomov
@ 2018-01-14  9:35   ` Sagi Grimberg
  0 siblings, 0 replies; 7+ messages in thread
From: Sagi Grimberg @ 2018-01-14  9:35 UTC (permalink / raw)
  To: Ilya Dryomov, linux-block
  Cc: Jens Axboe, Christoph Hellwig, Tejun Heo, David Disseldorp

Reviewed-by: Sagi Grimberg <sagi@grimberg.me>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro()
  2018-01-11 13:09 [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro() Ilya Dryomov
  2018-01-11 13:09 ` [PATCH v3 1/2] block: fail op_is_write() requests to read-only partitions Ilya Dryomov
  2018-01-11 13:09 ` [PATCH v3 2/2] block: add bdev_read_only() checks to common helpers Ilya Dryomov
@ 2018-01-18 11:16 ` Ilya Dryomov
  2018-01-18 19:57 ` Jens Axboe
  3 siblings, 0 replies; 7+ messages in thread
From: Ilya Dryomov @ 2018-01-18 11:16 UTC (permalink / raw)
  To: Jens Axboe
  Cc: linux-block, Christoph Hellwig, Tejun Heo, David Disseldorp,
	Sagi Grimberg

On Thu, Jan 11, 2018 at 2:09 PM, Ilya Dryomov <idryomov@gmail.com> wrote:
> Hello,
>
> I was doing some cleanup work on rbd BLKROSET handler and discovered
> that we ignore partition rw/ro setting (hd_struct->policy) for pretty
> much everything but straight writes.
>
> David (CCed) has blktests patches standing by.
>
> (Another aspect of this is that we don't enforce open(2) mode.  Tejun
> took a stab at this a few years ago, but his patch had to be reverted:
>
>   75f1dc0d076d ("block: check bdev_read_only() from blkdev_get()")
>   e51900f7d38c ("block: revert block_dev read-only check")
>
> It is a separate issue and refusing writes to read-only devices is
> obviously more important, but perhaps it's time to revisit that as
> well?)
>
> v2 -> v3:
> - lookup part only once; combine read-only check with existing
>   should_fail_request check
>
> v1 -> v2:
> - added unlikely() per Sagi's suggestion
>
> Thanks,
>
>                 Ilya
>
>
> Ilya Dryomov (2):
>   block: fail op_is_write() requests to read-only partitions
>   block: add bdev_read_only() checks to common helpers
>
>  block/blk-core.c | 56 ++++++++++++++++++++++++++++++++++++++------------------
>  block/blk-lib.c  | 12 ++++++++++++
>  2 files changed, 50 insertions(+), 18 deletions(-)

Jens, could you please pick these up for 4.16?

Thanks,

                Ilya

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro()
  2018-01-11 13:09 [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro() Ilya Dryomov
                   ` (2 preceding siblings ...)
  2018-01-18 11:16 ` [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro() Ilya Dryomov
@ 2018-01-18 19:57 ` Jens Axboe
  3 siblings, 0 replies; 7+ messages in thread
From: Jens Axboe @ 2018-01-18 19:57 UTC (permalink / raw)
  To: Ilya Dryomov, linux-block
  Cc: Christoph Hellwig, Tejun Heo, David Disseldorp, Sagi Grimberg

On 1/11/18 6:09 AM, Ilya Dryomov wrote:
> Hello,
> 
> I was doing some cleanup work on rbd BLKROSET handler and discovered
> that we ignore partition rw/ro setting (hd_struct->policy) for pretty
> much everything but straight writes.
> 
> David (CCed) has blktests patches standing by.
> 
> (Another aspect of this is that we don't enforce open(2) mode.  Tejun
> took a stab at this a few years ago, but his patch had to be reverted:
> 
>   75f1dc0d076d ("block: check bdev_read_only() from blkdev_get()")
>   e51900f7d38c ("block: revert block_dev read-only check")
> 
> It is a separate issue and refusing writes to read-only devices is
> obviously more important, but perhaps it's time to revisit that as
> well?)

Applied for 4.16, thanks.

-- 
Jens Axboe

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-01-18 19:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-11 13:09 [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro() Ilya Dryomov
2018-01-11 13:09 ` [PATCH v3 1/2] block: fail op_is_write() requests to read-only partitions Ilya Dryomov
2018-01-14  9:35   ` Sagi Grimberg
2018-01-11 13:09 ` [PATCH v3 2/2] block: add bdev_read_only() checks to common helpers Ilya Dryomov
2018-01-14  9:35   ` Sagi Grimberg
2018-01-18 11:16 ` [PATCH v3 0/2] block: enforce ioctl(BLKROSET) and set_disk_ro() Ilya Dryomov
2018-01-18 19:57 ` Jens Axboe

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.