* [PATCH] dm thin: reject metadata and data device aliases
@ 2026-10-26 10:27 Eduard Zateev
2026-10-26 22:40 ` Mikulas Patocka
0 siblings, 1 reply; 2+ messages in thread
From: Eduard Zateev @ 2026-10-26 10:27 UTC (permalink / raw)
To: dm-devel
Cc: agk, snitzer, mpatocka, bmarzins, linux-kernel,
syzbot+83827f9a59abe148bff4
From: angel <angel@localhost.localdomain>
The thin-pool target rejects identical argument strings, but two names for
the same block device bypass the check. In read-only metadata mode, opening
metadata first and data with write mode invokes dm_get_device()
upgrade_mode().
That swaps and frees the old dm_dev while pool_ctr retains metadata_dev,
causing a slab-use-after-free when __pool_find() reads metadata_dev->bdev.
Open the data device before metadata so an alias cannot trigger a mode
upgrade between the two references. Compare the opened block devices
and reject aliases before using either device. Adjust the error paths to
release the devices in the matching order.
Reported-by: syzbot+83827f9a59abe148bff4@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=83827f9a59abe148bff4
Fixes: 70de2cbda8a5 ("dm thin: add sanity checks to thin-pool and external snapshot creation")
Signed-off-by: Eduard Zateev <hackerowskiy@gmail.com>
---
drivers/md/dm-thin.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 358ed77ff..0899cbaf9 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -3326,17 +3326,24 @@ static int pool_ctr(struct dm_target *ti, unsigned int argc, char **argv)
metadata_mode = BLK_OPEN_READ |
((pf.mode == PM_READ_ONLY) ? 0 : BLK_OPEN_WRITE);
+ r = dm_get_device(ti, argv[1], BLK_OPEN_READ | BLK_OPEN_WRITE, &data_dev);
+ if (r) {
+ ti->error = "Error getting data device";
+ goto out_unlock;
+ }
+
r = dm_get_device(ti, argv[0], metadata_mode, &metadata_dev);
if (r) {
ti->error = "Error opening metadata block device";
- goto out_unlock;
+ goto out_data;
}
warn_if_metadata_device_too_big(metadata_dev->bdev);
- r = dm_get_device(ti, argv[1], BLK_OPEN_READ | BLK_OPEN_WRITE, &data_dev);
- if (r) {
- ti->error = "Error getting data device";
- goto out_metadata;
+ /* make sure metadata and data are different devices */
+ if (metadata_dev->bdev == data_dev->bdev) {
+ ti->error = "Error setting metadata or data device";
+ r = -EINVAL;
+ goto out;
}
if (kstrtoul(argv[2], 10, &block_size) || !block_size ||
@@ -3426,9 +3433,9 @@ static int pool_ctr(struct dm_target *ti, unsigned int argc, char **argv)
out_free_pt:
kfree(pt);
out:
- dm_put_device(ti, data_dev);
-out_metadata:
dm_put_device(ti, metadata_dev);
+out_data:
+ dm_put_device(ti, data_dev);
out_unlock:
mutex_unlock(&dm_thin_pool_table.mutex);
base-commit: 21a7f44fd0765fcc5194130b28767786eba1d1e7
--
2.56.0
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH] dm thin: reject metadata and data device aliases
2026-10-26 10:27 [PATCH] dm thin: reject metadata and data device aliases Eduard Zateev
@ 2026-10-26 22:40 ` Mikulas Patocka
0 siblings, 0 replies; 2+ messages in thread
From: Mikulas Patocka @ 2026-10-26 22:40 UTC (permalink / raw)
To: Eduard Zateev, Rahul Rao, Drif Abdelmalek Mohamed Said
Cc: dm-devel, agk, snitzer, bmarzins, linux-kernel,
syzbot+83827f9a59abe148bff4
Hi
If dm_get_device spuriously closes a device that was already open, it is a
bug in dm_get_device and it should be fixed there.
Note that we got 3 patches for this syzbot warning from 3 different
people. Please, cooperate next time and send just one patch.
Mikulas
On Mon, 26 Oct 2026, Eduard Zateev wrote:
> From: angel <angel@localhost.localdomain>
>
> The thin-pool target rejects identical argument strings, but two names for
> the same block device bypass the check. In read-only metadata mode, opening
> metadata first and data with write mode invokes dm_get_device()
> upgrade_mode().
> That swaps and frees the old dm_dev while pool_ctr retains metadata_dev,
> causing a slab-use-after-free when __pool_find() reads metadata_dev->bdev.
>
> Open the data device before metadata so an alias cannot trigger a mode
> upgrade between the two references. Compare the opened block devices
> and reject aliases before using either device. Adjust the error paths to
> release the devices in the matching order.
>
> Reported-by: syzbot+83827f9a59abe148bff4@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=83827f9a59abe148bff4
> Fixes: 70de2cbda8a5 ("dm thin: add sanity checks to thin-pool and external snapshot creation")
> Signed-off-by: Eduard Zateev <hackerowskiy@gmail.com>
> ---
> drivers/md/dm-thin.c | 21 ++++++++++++++-------
> 1 file changed, 14 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
> index 358ed77ff..0899cbaf9 100644
> --- a/drivers/md/dm-thin.c
> +++ b/drivers/md/dm-thin.c
> @@ -3326,17 +3326,24 @@ static int pool_ctr(struct dm_target *ti, unsigned int argc, char **argv)
>
> metadata_mode = BLK_OPEN_READ |
> ((pf.mode == PM_READ_ONLY) ? 0 : BLK_OPEN_WRITE);
> + r = dm_get_device(ti, argv[1], BLK_OPEN_READ | BLK_OPEN_WRITE, &data_dev);
> + if (r) {
> + ti->error = "Error getting data device";
> + goto out_unlock;
> + }
> +
> r = dm_get_device(ti, argv[0], metadata_mode, &metadata_dev);
> if (r) {
> ti->error = "Error opening metadata block device";
> - goto out_unlock;
> + goto out_data;
> }
> warn_if_metadata_device_too_big(metadata_dev->bdev);
>
> - r = dm_get_device(ti, argv[1], BLK_OPEN_READ | BLK_OPEN_WRITE, &data_dev);
> - if (r) {
> - ti->error = "Error getting data device";
> - goto out_metadata;
> + /* make sure metadata and data are different devices */
> + if (metadata_dev->bdev == data_dev->bdev) {
> + ti->error = "Error setting metadata or data device";
> + r = -EINVAL;
> + goto out;
> }
>
> if (kstrtoul(argv[2], 10, &block_size) || !block_size ||
> @@ -3426,9 +3433,9 @@ static int pool_ctr(struct dm_target *ti, unsigned int argc, char **argv)
> out_free_pt:
> kfree(pt);
> out:
> - dm_put_device(ti, data_dev);
> -out_metadata:
> dm_put_device(ti, metadata_dev);
> +out_data:
> + dm_put_device(ti, data_dev);
> out_unlock:
> mutex_unlock(&dm_thin_pool_table.mutex);
>
>
> base-commit: 21a7f44fd0765fcc5194130b28767786eba1d1e7
> --
> 2.56.0
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-26 22:40 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-26 10:27 [PATCH] dm thin: reject metadata and data device aliases Eduard Zateev
2026-10-26 22:40 ` Mikulas Patocka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®