From e607823069fec93972f0a6cb29e9b8ce7d4c3ebc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 10 May 2021 10:55:25 +0200 Subject: [PATCH] 4.14-stable patches added patches: dm-persistent-data-packed-struct-should-have-an-aligned-attribute-too.patch dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remove-after-table-load-fails.patch dm-space-map-common-fix-division-bug-in-sm_ll_find_free_block.patch tracing-map-all-pids-to-command-lines.patch --- ...should-have-an-aligned-attribute-too.patch | 76 +++++++++++ ...in-dev-remove-after-table-load-fails.patch | 91 +++++++++++++ ...ivision-bug-in-sm_ll_find_free_block.patch | 33 +++++ queue-4.14/series | 4 + ...racing-map-all-pids-to-command-lines.patch | 123 ++++++++++++++++++ 5 files changed, 327 insertions(+) create mode 100644 queue-4.14/dm-persistent-data-packed-struct-should-have-an-aligned-attribute-too.patch create mode 100644 queue-4.14/dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remove-after-table-load-fails.patch create mode 100644 queue-4.14/dm-space-map-common-fix-division-bug-in-sm_ll_find_free_block.patch create mode 100644 queue-4.14/tracing-map-all-pids-to-command-lines.patch diff --git a/queue-4.14/dm-persistent-data-packed-struct-should-have-an-aligned-attribute-too.patch b/queue-4.14/dm-persistent-data-packed-struct-should-have-an-aligned-attribute-too.patch new file mode 100644 index 00000000000..9a20cbcc5d4 --- /dev/null +++ b/queue-4.14/dm-persistent-data-packed-struct-should-have-an-aligned-attribute-too.patch @@ -0,0 +1,76 @@ +From a88b2358f1da2c9f9fcc432f2e0a79617fea397c Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Mon, 29 Mar 2021 16:34:57 +0100 +Subject: dm persistent data: packed struct should have an aligned() attribute too + +From: Joe Thornber + +commit a88b2358f1da2c9f9fcc432f2e0a79617fea397c upstream. + +Otherwise most non-x86 architectures (e.g. riscv, arm) will resort to +byte-by-byte access. + +Cc: stable@vger.kernel.org +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/persistent-data/dm-btree-internal.h | 4 ++-- + drivers/md/persistent-data/dm-space-map-common.h | 8 ++++---- + 2 files changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/md/persistent-data/dm-btree-internal.h ++++ b/drivers/md/persistent-data/dm-btree-internal.h +@@ -34,12 +34,12 @@ struct node_header { + __le32 max_entries; + __le32 value_size; + __le32 padding; +-} __packed; ++} __attribute__((packed, aligned(8))); + + struct btree_node { + struct node_header header; + __le64 keys[0]; +-} __packed; ++} __attribute__((packed, aligned(8))); + + + /* +--- a/drivers/md/persistent-data/dm-space-map-common.h ++++ b/drivers/md/persistent-data/dm-space-map-common.h +@@ -33,7 +33,7 @@ struct disk_index_entry { + __le64 blocknr; + __le32 nr_free; + __le32 none_free_before; +-} __packed; ++} __attribute__ ((packed, aligned(8))); + + + #define MAX_METADATA_BITMAPS 255 +@@ -43,7 +43,7 @@ struct disk_metadata_index { + __le64 blocknr; + + struct disk_index_entry index[MAX_METADATA_BITMAPS]; +-} __packed; ++} __attribute__ ((packed, aligned(8))); + + struct ll_disk; + +@@ -86,7 +86,7 @@ struct disk_sm_root { + __le64 nr_allocated; + __le64 bitmap_root; + __le64 ref_count_root; +-} __packed; ++} __attribute__ ((packed, aligned(8))); + + #define ENTRIES_PER_BYTE 4 + +@@ -94,7 +94,7 @@ struct disk_bitmap_header { + __le32 csum; + __le32 not_used; + __le64 blocknr; +-} __packed; ++} __attribute__ ((packed, aligned(8))); + + enum allocation_event { + SM_NONE, diff --git a/queue-4.14/dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remove-after-table-load-fails.patch b/queue-4.14/dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remove-after-table-load-fails.patch new file mode 100644 index 00000000000..a895bb04188 --- /dev/null +++ b/queue-4.14/dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remove-after-table-load-fails.patch @@ -0,0 +1,91 @@ +From 8e947c8f4a5620df77e43c9c75310dc510250166 Mon Sep 17 00:00:00 2001 +From: Benjamin Block +Date: Thu, 29 Apr 2021 23:37:00 +0200 +Subject: dm rq: fix double free of blk_mq_tag_set in dev remove after table load fails + +From: Benjamin Block + +commit 8e947c8f4a5620df77e43c9c75310dc510250166 upstream. + +When loading a device-mapper table for a request-based mapped device, +and the allocation/initialization of the blk_mq_tag_set for the device +fails, a following device remove will cause a double free. + +E.g. (dmesg): + device-mapper: core: Cannot initialize queue for request-based dm-mq mapped device + device-mapper: ioctl: unable to set up device queue for new table. + Unable to handle kernel pointer dereference in virtual kernel address space + Failing address: 0305e098835de000 TEID: 0305e098835de803 + Fault in home space mode while using kernel ASCE. + AS:000000025efe0007 R3:0000000000000024 + Oops: 0038 ilc:3 [#1] SMP + Modules linked in: ... lots of modules ... + Supported: Yes, External + CPU: 0 PID: 7348 Comm: multipathd Kdump: loaded Tainted: G W X 5.3.18-53-default #1 SLE15-SP3 + Hardware name: IBM 8561 T01 7I2 (LPAR) + Krnl PSW : 0704e00180000000 000000025e368eca (kfree+0x42/0x330) + R:0 T:1 IO:1 EX:1 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3 + Krnl GPRS: 000000000000004a 000000025efe5230 c1773200d779968d 0000000000000000 + 000000025e520270 000000025e8d1b40 0000000000000003 00000007aae10000 + 000000025e5202a2 0000000000000001 c1773200d779968d 0305e098835de640 + 00000007a8170000 000003ff80138650 000000025e5202a2 000003e00396faa8 + Krnl Code: 000000025e368eb8: c4180041e100 lgrl %r1,25eba50b8 + 000000025e368ebe: ecba06b93a55 risbg %r11,%r10,6,185,58 + #000000025e368ec4: e3b010000008 ag %r11,0(%r1) + >000000025e368eca: e310b0080004 lg %r1,8(%r11) + 000000025e368ed0: a7110001 tmll %r1,1 + 000000025e368ed4: a7740129 brc 7,25e369126 + 000000025e368ed8: e320b0080004 lg %r2,8(%r11) + 000000025e368ede: b904001b lgr %r1,%r11 + Call Trace: + [<000000025e368eca>] kfree+0x42/0x330 + [<000000025e5202a2>] blk_mq_free_tag_set+0x72/0xb8 + [<000003ff801316a8>] dm_mq_cleanup_mapped_device+0x38/0x50 [dm_mod] + [<000003ff80120082>] free_dev+0x52/0xd0 [dm_mod] + [<000003ff801233f0>] __dm_destroy+0x150/0x1d0 [dm_mod] + [<000003ff8012bb9a>] dev_remove+0x162/0x1c0 [dm_mod] + [<000003ff8012a988>] ctl_ioctl+0x198/0x478 [dm_mod] + [<000003ff8012ac8a>] dm_ctl_ioctl+0x22/0x38 [dm_mod] + [<000000025e3b11ee>] ksys_ioctl+0xbe/0xe0 + [<000000025e3b127a>] __s390x_sys_ioctl+0x2a/0x40 + [<000000025e8c15ac>] system_call+0xd8/0x2c8 + Last Breaking-Event-Address: + [<000000025e52029c>] blk_mq_free_tag_set+0x6c/0xb8 + Kernel panic - not syncing: Fatal exception: panic_on_oops + +When allocation/initialization of the blk_mq_tag_set fails in +dm_mq_init_request_queue(), it is uninitialized/freed, but the pointer +is not reset to NULL; so when dev_remove() later gets into +dm_mq_cleanup_mapped_device() it sees the pointer and tries to +uninitialize and free it again. + +Fix this by setting the pointer to NULL in dm_mq_init_request_queue() +error-handling. Also set it to NULL in dm_mq_cleanup_mapped_device(). + +Cc: # 4.6+ +Fixes: 1c357a1e86a4 ("dm: allocate blk_mq_tag_set rather than embed in mapped_device") +Signed-off-by: Benjamin Block +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/dm-rq.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/md/dm-rq.c ++++ b/drivers/md/dm-rq.c +@@ -822,6 +822,7 @@ out_tag_set: + blk_mq_free_tag_set(md->tag_set); + out_kfree_tag_set: + kfree(md->tag_set); ++ md->tag_set = NULL; + + return err; + } +@@ -831,6 +832,7 @@ void dm_mq_cleanup_mapped_device(struct + if (md->tag_set) { + blk_mq_free_tag_set(md->tag_set); + kfree(md->tag_set); ++ md->tag_set = NULL; + } + } + diff --git a/queue-4.14/dm-space-map-common-fix-division-bug-in-sm_ll_find_free_block.patch b/queue-4.14/dm-space-map-common-fix-division-bug-in-sm_ll_find_free_block.patch new file mode 100644 index 00000000000..915e850c851 --- /dev/null +++ b/queue-4.14/dm-space-map-common-fix-division-bug-in-sm_ll_find_free_block.patch @@ -0,0 +1,33 @@ +From 5208692e80a1f3c8ce2063a22b675dd5589d1d80 Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Tue, 13 Apr 2021 09:11:53 +0100 +Subject: dm space map common: fix division bug in sm_ll_find_free_block() + +From: Joe Thornber + +commit 5208692e80a1f3c8ce2063a22b675dd5589d1d80 upstream. + +This division bug meant the search for free metadata space could skip +the final allocation bitmap's worth of entries. Fix affects DM thinp, +cache and era targets. + +Cc: stable@vger.kernel.org +Signed-off-by: Joe Thornber +Tested-by: Ming-Hung Tsai +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman +--- + drivers/md/persistent-data/dm-space-map-common.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/md/persistent-data/dm-space-map-common.c ++++ b/drivers/md/persistent-data/dm-space-map-common.c +@@ -337,6 +337,8 @@ int sm_ll_find_free_block(struct ll_disk + */ + begin = do_div(index_begin, ll->entries_per_block); + end = do_div(end, ll->entries_per_block); ++ if (end == 0) ++ end = ll->entries_per_block; + + for (i = index_begin; i < index_end; i++, begin = 0) { + struct dm_block *blk; diff --git a/queue-4.14/series b/queue-4.14/series index d6098d9dfdf..e9229762199 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -96,3 +96,7 @@ usb-gadget-dummy_hcd-fix-gpf-in-gadget_setup.patch usb-gadget-fix-double-free-of-device-descriptor-pointers.patch usb-gadget-function-f_fs-string-table-fix-for-multiple-languages.patch usb-dwc3-gadget-fix-start_transfer-link-state-check.patch +tracing-map-all-pids-to-command-lines.patch +dm-persistent-data-packed-struct-should-have-an-aligned-attribute-too.patch +dm-space-map-common-fix-division-bug-in-sm_ll_find_free_block.patch +dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remove-after-table-load-fails.patch diff --git a/queue-4.14/tracing-map-all-pids-to-command-lines.patch b/queue-4.14/tracing-map-all-pids-to-command-lines.patch new file mode 100644 index 00000000000..604a9f4253e --- /dev/null +++ b/queue-4.14/tracing-map-all-pids-to-command-lines.patch @@ -0,0 +1,123 @@ +From 785e3c0a3a870e72dc530856136ab4c8dd207128 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (VMware)" +Date: Tue, 27 Apr 2021 11:32:07 -0400 +Subject: tracing: Map all PIDs to command lines + +From: Steven Rostedt (VMware) + +commit 785e3c0a3a870e72dc530856136ab4c8dd207128 upstream. + +The default max PID is set by PID_MAX_DEFAULT, and the tracing +infrastructure uses this number to map PIDs to the comm names of the +tasks, such output of the trace can show names from the recorded PIDs in +the ring buffer. This mapping is also exported to user space via the +"saved_cmdlines" file in the tracefs directory. + +But currently the mapping expects the PIDs to be less than +PID_MAX_DEFAULT, which is the default maximum and not the real maximum. +Recently, systemd will increases the maximum value of a PID on the system, +and when tasks are traced that have a PID higher than PID_MAX_DEFAULT, its +comm is not recorded. This leads to the entire trace to have "<...>" as +the comm name, which is pretty useless. + +Instead, keep the array mapping the size of PID_MAX_DEFAULT, but instead +of just mapping the index to the comm, map a mask of the PID +(PID_MAX_DEFAULT - 1) to the comm, and find the full PID from the +map_cmdline_to_pid array (that already exists). + +This bug goes back to the beginning of ftrace, but hasn't been an issue +until user space started increasing the maximum value of PIDs. + +Link: https://lkml.kernel.org/r/20210427113207.3c601884@gandalf.local.home + +Cc: stable@vger.kernel.org +Fixes: bc0c38d139ec7 ("ftrace: latency tracer infrastructure") +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/trace.c | 41 +++++++++++++++-------------------------- + 1 file changed, 15 insertions(+), 26 deletions(-) + +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -1928,14 +1928,13 @@ static void tracing_stop_tr(struct trace + + static int trace_save_cmdline(struct task_struct *tsk) + { +- unsigned pid, idx; ++ unsigned tpid, idx; + + /* treat recording of idle task as a success */ + if (!tsk->pid) + return 1; + +- if (unlikely(tsk->pid > PID_MAX_DEFAULT)) +- return 0; ++ tpid = tsk->pid & (PID_MAX_DEFAULT - 1); + + /* + * It's not the end of the world if we don't get +@@ -1946,26 +1945,15 @@ static int trace_save_cmdline(struct tas + if (!arch_spin_trylock(&trace_cmdline_lock)) + return 0; + +- idx = savedcmd->map_pid_to_cmdline[tsk->pid]; ++ idx = savedcmd->map_pid_to_cmdline[tpid]; + if (idx == NO_CMDLINE_MAP) { + idx = (savedcmd->cmdline_idx + 1) % savedcmd->cmdline_num; + +- /* +- * Check whether the cmdline buffer at idx has a pid +- * mapped. We are going to overwrite that entry so we +- * need to clear the map_pid_to_cmdline. Otherwise we +- * would read the new comm for the old pid. +- */ +- pid = savedcmd->map_cmdline_to_pid[idx]; +- if (pid != NO_CMDLINE_MAP) +- savedcmd->map_pid_to_cmdline[pid] = NO_CMDLINE_MAP; +- +- savedcmd->map_cmdline_to_pid[idx] = tsk->pid; +- savedcmd->map_pid_to_cmdline[tsk->pid] = idx; +- ++ savedcmd->map_pid_to_cmdline[tpid] = idx; + savedcmd->cmdline_idx = idx; + } + ++ savedcmd->map_cmdline_to_pid[idx] = tsk->pid; + set_cmdline(idx, tsk->comm); + + arch_spin_unlock(&trace_cmdline_lock); +@@ -1976,6 +1964,7 @@ static int trace_save_cmdline(struct tas + static void __trace_find_cmdline(int pid, char comm[]) + { + unsigned map; ++ int tpid; + + if (!pid) { + strcpy(comm, ""); +@@ -1987,16 +1976,16 @@ static void __trace_find_cmdline(int pid + return; + } + +- if (pid > PID_MAX_DEFAULT) { +- strcpy(comm, "<...>"); +- return; ++ tpid = pid & (PID_MAX_DEFAULT - 1); ++ map = savedcmd->map_pid_to_cmdline[tpid]; ++ if (map != NO_CMDLINE_MAP) { ++ tpid = savedcmd->map_cmdline_to_pid[map]; ++ if (tpid == pid) { ++ strlcpy(comm, get_saved_cmdlines(map), TASK_COMM_LEN); ++ return; ++ } + } +- +- map = savedcmd->map_pid_to_cmdline[pid]; +- if (map != NO_CMDLINE_MAP) +- strlcpy(comm, get_saved_cmdlines(map), TASK_COMM_LEN); +- else +- strcpy(comm, "<...>"); ++ strcpy(comm, "<...>"); + } + + void trace_find_cmdline(int pid, char comm[]) -- 2.47.3