]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 May 2021 08:55:25 +0000 (10:55 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 May 2021 08:55:25 +0000 (10:55 +0200)
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

queue-4.14/dm-persistent-data-packed-struct-should-have-an-aligned-attribute-too.patch [new file with mode: 0644]
queue-4.14/dm-rq-fix-double-free-of-blk_mq_tag_set-in-dev-remove-after-table-load-fails.patch [new file with mode: 0644]
queue-4.14/dm-space-map-common-fix-division-bug-in-sm_ll_find_free_block.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/tracing-map-all-pids-to-command-lines.patch [new file with mode: 0644]

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 (file)
index 0000000..9a20cbc
--- /dev/null
@@ -0,0 +1,76 @@
+From a88b2358f1da2c9f9fcc432f2e0a79617fea397c Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+Date: Mon, 29 Mar 2021 16:34:57 +0100
+Subject: dm persistent data: packed struct should have an aligned() attribute too
+
+From: Joe Thornber <ejt@redhat.com>
+
+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 <ejt@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..a895bb0
--- /dev/null
@@ -0,0 +1,91 @@
+From 8e947c8f4a5620df77e43c9c75310dc510250166 Mon Sep 17 00:00:00 2001
+From: Benjamin Block <bblock@linux.ibm.com>
+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 <bblock@linux.ibm.com>
+
+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: <stable@vger.kernel.org> # 4.6+
+Fixes: 1c357a1e86a4 ("dm: allocate blk_mq_tag_set rather than embed in mapped_device")
+Signed-off-by: Benjamin Block <bblock@linux.ibm.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..915e850
--- /dev/null
@@ -0,0 +1,33 @@
+From 5208692e80a1f3c8ce2063a22b675dd5589d1d80 Mon Sep 17 00:00:00 2001
+From: Joe Thornber <ejt@redhat.com>
+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 <ejt@redhat.com>
+
+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 <ejt@redhat.com>
+Tested-by: Ming-Hung Tsai <mtsai@redhat.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
index d6098d9dfdf22b20536411c7934920d2f1667c3b..e922976219908a0cc64737d28c40d679ecdeabba 100644 (file)
@@ -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 (file)
index 0000000..604a9f4
--- /dev/null
@@ -0,0 +1,123 @@
+From 785e3c0a3a870e72dc530856136ab4c8dd207128 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Tue, 27 Apr 2021 11:32:07 -0400
+Subject: tracing: Map all PIDs to command lines
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+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) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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, "<idle>");
+@@ -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[])