diff mbox series

[1/2] Fail I/O to thin pool devices

Message ID 20230207011849.1343-1-demi@invisiblethingslab.com (mailing list archive)
State Rejected, archived
Delegated to: Mike Snitzer
Headers show
Series [1/2] Fail I/O to thin pool devices | expand

Commit Message

Demi Marie Obenour Feb. 7, 2023, 1:18 a.m. UTC
A thin pool device currently just passes all I/O to its origin device,
but this is a footgun: the user might not realize that tools that
operate on thin pool metadata must operate on the metadata volume.  This
could have security implications.

Fix this by failing all I/O to thin pool devices.

Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com>
---
 drivers/md/dm-thin.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

Comments

Joe Thornber Feb. 7, 2023, 3:02 p.m. UTC | #1
Nack.

I don't see the security issue; how is this any different from running the
thin tools on any incorrect device?  Or even the data device that the pool
is mirroring.  In general the thin tools don't modify the metadata they're
running on.  If you know of a security issue with the thin tools please let
me know.


On Tue, Feb 7, 2023 at 7:56 AM Demi Marie Obenour <
demi@invisiblethingslab.com> wrote:

> A thin pool device currently just passes all I/O to its origin device,
> but this is a footgun: the user might not realize that tools that
> operate on thin pool metadata must operate on the metadata volume.  This
> could have security implications.
>
> Fix this by failing all I/O to thin pool devices.
>
> Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com>
> ---
>  drivers/md/dm-thin.c | 17 ++++++-----------
>  1 file changed, 6 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
> index
> 64cfcf46881dc5d87d5dfdb5650ba9babd32cd31..d85fdbd782ae5426003c99a4b4bf53818cc85efa
> 100644
> --- a/drivers/md/dm-thin.c
> +++ b/drivers/md/dm-thin.c
> @@ -3405,19 +3405,14 @@ static int pool_ctr(struct dm_target *ti, unsigned
> argc, char **argv)
>
>  static int pool_map(struct dm_target *ti, struct bio *bio)
>  {
> -       int r;
> -       struct pool_c *pt = ti->private;
> -       struct pool *pool = pt->pool;
> -
>         /*
> -        * As this is a singleton target, ti->begin is always zero.
> +        * Previously, access to the pool was passed down to the origin
> device.
> +        * However, this turns out to be error-prone: if the user runs any
> of
> +        * the thin tools on the pool device, the tools could wind up
> parsing
> +        * potentially attacker-controlled data.  This mistake has actually
> +        * happened in practice.  Therefore, fail all I/O on the pool
> device.
>          */
> -       spin_lock_irq(&pool->lock);
> -       bio_set_dev(bio, pt->data_dev->bdev);
> -       r = DM_MAPIO_REMAPPED;
> -       spin_unlock_irq(&pool->lock);
> -
> -       return r;
> +       return -EIO;
>  }
>
>  static int maybe_resize_data_dev(struct dm_target *ti, bool *need_commit)
> --
> Sincerely,
> Demi Marie Obenour (she/her/hers)
> Invisible Things Lab
>
> --
> dm-devel mailing list
> dm-devel@redhat.com
> https://listman.redhat.com/mailman/listinfo/dm-devel
>
>
--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
Demi Marie Obenour Feb. 7, 2023, 4:19 p.m. UTC | #2
On Tue, Feb 07, 2023 at 03:02:51PM +0000, Joe Thornber wrote:
> Nack.
> 
> I don't see the security issue; how is this any different from running the
> thin tools on any incorrect device?  Or even the data device that the pool
> is mirroring.

I special-cased the pool device for two reasons:

1. I have run the thin tools on the pool device myself before realising
   that they needed to be run on the metadata device.  It took me a
   while to realize that I was using the wrong device.  I have not made
   that mistake with other devices, which is why I special-cased the
   pool device in this patch.

2. Doing I/O to the pool device is pointless.  The pool device is
   strictly slower than the data device and exposes the exact same
   contents, so accessing the pool device directly is never what one
   wants.

If there are backwards compatibility concerns, I could make this be
controlled by a Kconfig option, module parameter, or both.

> In general the thin tools don't modify the metadata they're
> running on.  If you know of a security issue with the thin tools please let
> me know.

I am not aware of a concrete security problem, but in general I prefer
not to expose unnecessary attack surface.
Zdenek Kabelac Feb. 7, 2023, 5:50 p.m. UTC | #3
Dne 07. 02. 23 v 17:19 Demi Marie Obenour napsal(a):
> On Tue, Feb 07, 2023 at 03:02:51PM +0000, Joe Thornber wrote:
>> Nack.
>>
>> I don't see the security issue; how is this any different from running the
>> thin tools on any incorrect device?  Or even the data device that the pool
>> is mirroring.
> 
> I special-cased the pool device for two reasons:
> 
> 1. I have run the thin tools on the pool device myself before realising
>     that they needed to be run on the metadata device.  It took me a
>     while to realize that I was using the wrong device.  I have not made
>     that mistake with other devices, which is why I special-cased the
>     pool device in this patch.
> 
> 2. Doing I/O to the pool device is pointless.  The pool device is
>     strictly slower than the data device and exposes the exact same
>     contents, so accessing the pool device directly is never what one
>     wants.
> 
> If there are backwards compatibility concerns, I could make this be
> controlled by a Kconfig option, module parameter, or both.
> 
>> In general the thin tools don't modify the metadata they're
>> running on.  If you know of a security issue with the thin tools please let
>> me know.
> 
> I am not aware of a concrete security problem, but in general I prefer
> not to expose unnecessary attack surface.

lvm2 introduced 'protection' layer device - which keeps   -tpool opened and 
thus avoid possibility to use  i.e.  mkfs on thin-pool itself (as it requires 
exclusive open)

Zdenek

--
dm-devel mailing list
dm-devel@redhat.com
https://listman.redhat.com/mailman/listinfo/dm-devel
diff mbox series

Patch

diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 64cfcf46881dc5d87d5dfdb5650ba9babd32cd31..d85fdbd782ae5426003c99a4b4bf53818cc85efa 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -3405,19 +3405,14 @@  static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
 
 static int pool_map(struct dm_target *ti, struct bio *bio)
 {
-	int r;
-	struct pool_c *pt = ti->private;
-	struct pool *pool = pt->pool;
-
 	/*
-	 * As this is a singleton target, ti->begin is always zero.
+	 * Previously, access to the pool was passed down to the origin device.
+	 * However, this turns out to be error-prone: if the user runs any of
+	 * the thin tools on the pool device, the tools could wind up parsing
+	 * potentially attacker-controlled data.  This mistake has actually
+	 * happened in practice.  Therefore, fail all I/O on the pool device.
 	 */
-	spin_lock_irq(&pool->lock);
-	bio_set_dev(bio, pt->data_dev->bdev);
-	r = DM_MAPIO_REMAPPED;
-	spin_unlock_irq(&pool->lock);
-
-	return r;
+	return -EIO;
 }
 
 static int maybe_resize_data_dev(struct dm_target *ti, bool *need_commit)