]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.19.34/dm-thin-add-sanity-checks-to-thin-pool-and-external-.patch
Linux 4.19.34
[thirdparty/kernel/stable-queue.git] / releases / 4.19.34 / dm-thin-add-sanity-checks-to-thin-pool-and-external-.patch
1 From a13a43f1b0f1fee784892cd84aece7f07bb5499e Mon Sep 17 00:00:00 2001
2 From: "Jason Cai (Xiang Feng)" <jason.cai.kern@gmail.com>
3 Date: Sun, 20 Jan 2019 22:39:13 +0800
4 Subject: dm thin: add sanity checks to thin-pool and external snapshot
5 creation
6
7 [ Upstream commit 70de2cbda8a5d788284469e755f8b097d339c240 ]
8
9 Invoking dm_get_device() twice on the same device path with different
10 modes is dangerous. Because in that case, upgrade_mode() will alloc a
11 new 'dm_dev' and free the old one, which may be referenced by a previous
12 caller. Dereferencing the dangling pointer will trigger kernel NULL
13 pointer dereference.
14
15 The following two cases can reproduce this issue. Actually, they are
16 invalid setups that must be disallowed, e.g.:
17
18 1. Creating a thin-pool with read_only mode, and the same device as
19 both metadata and data.
20
21 dmsetup create thinp --table \
22 "0 41943040 thin-pool /dev/vdb /dev/vdb 128 0 1 read_only"
23
24 BUG: unable to handle kernel NULL pointer dereference at 0000000000000080
25 ...
26 Call Trace:
27 new_read+0xfb/0x110 [dm_bufio]
28 dm_bm_read_lock+0x43/0x190 [dm_persistent_data]
29 ? kmem_cache_alloc_trace+0x15c/0x1e0
30 __create_persistent_data_objects+0x65/0x3e0 [dm_thin_pool]
31 dm_pool_metadata_open+0x8c/0xf0 [dm_thin_pool]
32 pool_ctr.cold.79+0x213/0x913 [dm_thin_pool]
33 ? realloc_argv+0x50/0x70 [dm_mod]
34 dm_table_add_target+0x14e/0x330 [dm_mod]
35 table_load+0x122/0x2e0 [dm_mod]
36 ? dev_status+0x40/0x40 [dm_mod]
37 ctl_ioctl+0x1aa/0x3e0 [dm_mod]
38 dm_ctl_ioctl+0xa/0x10 [dm_mod]
39 do_vfs_ioctl+0xa2/0x600
40 ? handle_mm_fault+0xda/0x200
41 ? __do_page_fault+0x26c/0x4f0
42 ksys_ioctl+0x60/0x90
43 __x64_sys_ioctl+0x16/0x20
44 do_syscall_64+0x55/0x150
45 entry_SYSCALL_64_after_hwframe+0x44/0xa9
46
47 2. Creating a external snapshot using the same thin-pool device.
48
49 dmsetup create thinp --table \
50 "0 41943040 thin-pool /dev/vdc /dev/vdb 128 0 2 ignore_discard"
51 dmsetup message /dev/mapper/thinp 0 "create_thin 0"
52 dmsetup create snap --table \
53 "0 204800 thin /dev/mapper/thinp 0 /dev/mapper/thinp"
54
55 BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
56 ...
57 Call Trace:
58 ? __alloc_pages_nodemask+0x13c/0x2e0
59 retrieve_status+0xa5/0x1f0 [dm_mod]
60 ? dm_get_live_or_inactive_table.isra.7+0x20/0x20 [dm_mod]
61 table_status+0x61/0xa0 [dm_mod]
62 ctl_ioctl+0x1aa/0x3e0 [dm_mod]
63 dm_ctl_ioctl+0xa/0x10 [dm_mod]
64 do_vfs_ioctl+0xa2/0x600
65 ksys_ioctl+0x60/0x90
66 ? ksys_write+0x4f/0xb0
67 __x64_sys_ioctl+0x16/0x20
68 do_syscall_64+0x55/0x150
69 entry_SYSCALL_64_after_hwframe+0x44/0xa9
70
71 Signed-off-by: Jason Cai (Xiang Feng) <jason.cai@linux.alibaba.com>
72 Signed-off-by: Mike Snitzer <snitzer@redhat.com>
73 Signed-off-by: Sasha Levin <sashal@kernel.org>
74 ---
75 drivers/md/dm-thin.c | 13 +++++++++++++
76 1 file changed, 13 insertions(+)
77
78 diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
79 index cd4220ee7004..435a2ee4a392 100644
80 --- a/drivers/md/dm-thin.c
81 +++ b/drivers/md/dm-thin.c
82 @@ -3283,6 +3283,13 @@ static int pool_ctr(struct dm_target *ti, unsigned argc, char **argv)
83 as.argc = argc;
84 as.argv = argv;
85
86 + /* make sure metadata and data are different devices */
87 + if (!strcmp(argv[0], argv[1])) {
88 + ti->error = "Error setting metadata or data device";
89 + r = -EINVAL;
90 + goto out_unlock;
91 + }
92 +
93 /*
94 * Set default pool features.
95 */
96 @@ -4167,6 +4174,12 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
97 tc->sort_bio_list = RB_ROOT;
98
99 if (argc == 3) {
100 + if (!strcmp(argv[0], argv[2])) {
101 + ti->error = "Error setting origin device";
102 + r = -EINVAL;
103 + goto bad_origin_dev;
104 + }
105 +
106 r = dm_get_device(ti, argv[2], FMODE_READ, &origin_dev);
107 if (r) {
108 ti->error = "Error opening origin device";
109 --
110 2.19.1
111