]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 19 Jul 2021 12:15:39 +0000 (14:15 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 19 Jul 2021 12:15:39 +0000 (14:15 +0200)
added patches:
cgroup-verify-that-source-is-a-string.patch
fbmem-do-not-delete-the-mode-that-is-still-in-use.patch
scsi-core-fix-bad-pointer-dereference-when-ehandler-kthread-is-invalid.patch
tracing-do-not-reference-char-as-a-string-in-histograms.patch

queue-5.4/cgroup-verify-that-source-is-a-string.patch [new file with mode: 0644]
queue-5.4/fbmem-do-not-delete-the-mode-that-is-still-in-use.patch [new file with mode: 0644]
queue-5.4/scsi-core-fix-bad-pointer-dereference-when-ehandler-kthread-is-invalid.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/tracing-do-not-reference-char-as-a-string-in-histograms.patch [new file with mode: 0644]

diff --git a/queue-5.4/cgroup-verify-that-source-is-a-string.patch b/queue-5.4/cgroup-verify-that-source-is-a-string.patch
new file mode 100644 (file)
index 0000000..03d2373
--- /dev/null
@@ -0,0 +1,64 @@
+From 3b0462726e7ef281c35a7a4ae33e93ee2bc9975b Mon Sep 17 00:00:00 2001
+From: Christian Brauner <christian.brauner@ubuntu.com>
+Date: Wed, 14 Jul 2021 15:47:49 +0200
+Subject: cgroup: verify that source is a string
+
+From: Christian Brauner <christian.brauner@ubuntu.com>
+
+commit 3b0462726e7ef281c35a7a4ae33e93ee2bc9975b upstream.
+
+The following sequence can be used to trigger a UAF:
+
+    int fscontext_fd = fsopen("cgroup");
+    int fd_null = open("/dev/null, O_RDONLY);
+    int fsconfig(fscontext_fd, FSCONFIG_SET_FD, "source", fd_null);
+    close_range(3, ~0U, 0);
+
+The cgroup v1 specific fs parser expects a string for the "source"
+parameter.  However, it is perfectly legitimate to e.g.  specify a file
+descriptor for the "source" parameter.  The fs parser doesn't know what
+a filesystem allows there.  So it's a bug to assume that "source" is
+always of type fs_value_is_string when it can reasonably also be
+fs_value_is_file.
+
+This assumption in the cgroup code causes a UAF because struct
+fs_parameter uses a union for the actual value.  Access to that union is
+guarded by the param->type member.  Since the cgroup paramter parser
+didn't check param->type but unconditionally moved param->string into
+fc->source a close on the fscontext_fd would trigger a UAF during
+put_fs_context() which frees fc->source thereby freeing the file stashed
+in param->file causing a UAF during a close of the fd_null.
+
+Fix this by verifying that param->type is actually a string and report
+an error if not.
+
+In follow up patches I'll add a new generic helper that can be used here
+and by other filesystems instead of this error-prone copy-pasta fix.
+But fixing it in here first makes backporting a it to stable a lot
+easier.
+
+Fixes: 8d2451f4994f ("cgroup1: switch to option-by-option parsing")
+Reported-by: syzbot+283ce5a46486d6acdbaf@syzkaller.appspotmail.com
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Alexander Viro <viro@zeniv.linux.org.uk>
+Cc: Dmitry Vyukov <dvyukov@google.com>
+Cc: <stable@kernel.org>
+Cc: syzkaller-bugs <syzkaller-bugs@googlegroups.com>
+Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/cgroup/cgroup-v1.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/kernel/cgroup/cgroup-v1.c
++++ b/kernel/cgroup/cgroup-v1.c
+@@ -918,6 +918,8 @@ int cgroup1_parse_param(struct fs_contex
+       opt = fs_parse(fc, &cgroup1_fs_parameters, param, &result);
+       if (opt == -ENOPARAM) {
+               if (strcmp(param->key, "source") == 0) {
++                      if (param->type != fs_value_is_string)
++                              return invalf(fc, "Non-string source");
+                       if (fc->source)
+                               return invalf(fc, "Multiple sources not supported");
+                       fc->source = param->string;
diff --git a/queue-5.4/fbmem-do-not-delete-the-mode-that-is-still-in-use.patch b/queue-5.4/fbmem-do-not-delete-the-mode-that-is-still-in-use.patch
new file mode 100644 (file)
index 0000000..d9ea8da
--- /dev/null
@@ -0,0 +1,85 @@
+From 0af778269a522c988ef0b4188556aba97fb420cc Mon Sep 17 00:00:00 2001
+From: Zhen Lei <thunder.leizhen@huawei.com>
+Date: Mon, 12 Jul 2021 16:55:44 +0800
+Subject: fbmem: Do not delete the mode that is still in use
+
+From: Zhen Lei <thunder.leizhen@huawei.com>
+
+commit 0af778269a522c988ef0b4188556aba97fb420cc upstream.
+
+The execution of fb_delete_videomode() is not based on the result of the
+previous fbcon_mode_deleted(). As a result, the mode is directly deleted,
+regardless of whether it is still in use, which may cause UAF.
+
+==================================================================
+BUG: KASAN: use-after-free in fb_mode_is_equal+0x36e/0x5e0 \
+drivers/video/fbdev/core/modedb.c:924
+Read of size 4 at addr ffff88807e0ddb1c by task syz-executor.0/18962
+
+CPU: 2 PID: 18962 Comm: syz-executor.0 Not tainted 5.10.45-rc1+ #3
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS ...
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x137/0x1be lib/dump_stack.c:118
+ print_address_description+0x6c/0x640 mm/kasan/report.c:385
+ __kasan_report mm/kasan/report.c:545 [inline]
+ kasan_report+0x13d/0x1e0 mm/kasan/report.c:562
+ fb_mode_is_equal+0x36e/0x5e0 drivers/video/fbdev/core/modedb.c:924
+ fbcon_mode_deleted+0x16a/0x220 drivers/video/fbdev/core/fbcon.c:2746
+ fb_set_var+0x1e1/0xdb0 drivers/video/fbdev/core/fbmem.c:975
+ do_fb_ioctl+0x4d9/0x6e0 drivers/video/fbdev/core/fbmem.c:1108
+ vfs_ioctl fs/ioctl.c:48 [inline]
+ __do_sys_ioctl fs/ioctl.c:753 [inline]
+ __se_sys_ioctl+0xfb/0x170 fs/ioctl.c:739
+ do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Freed by task 18960:
+ kasan_save_stack mm/kasan/common.c:48 [inline]
+ kasan_set_track+0x3d/0x70 mm/kasan/common.c:56
+ kasan_set_free_info+0x17/0x30 mm/kasan/generic.c:355
+ __kasan_slab_free+0x108/0x140 mm/kasan/common.c:422
+ slab_free_hook mm/slub.c:1541 [inline]
+ slab_free_freelist_hook+0xd6/0x1a0 mm/slub.c:1574
+ slab_free mm/slub.c:3139 [inline]
+ kfree+0xca/0x3d0 mm/slub.c:4121
+ fb_delete_videomode+0x56a/0x820 drivers/video/fbdev/core/modedb.c:1104
+ fb_set_var+0x1f3/0xdb0 drivers/video/fbdev/core/fbmem.c:978
+ do_fb_ioctl+0x4d9/0x6e0 drivers/video/fbdev/core/fbmem.c:1108
+ vfs_ioctl fs/ioctl.c:48 [inline]
+ __do_sys_ioctl fs/ioctl.c:753 [inline]
+ __se_sys_ioctl+0xfb/0x170 fs/ioctl.c:739
+ do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
+ entry_SYSCALL_64_after_hwframe+0x44/0xa9
+
+Fixes: 13ff178ccd6d ("fbcon: Call fbcon_mode_deleted/new_modelist directly")
+Signed-off-by: Zhen Lei <thunder.leizhen@huawei.com>
+Cc: <stable@vger.kernel.org> # v5.3+
+Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
+Link: https://patchwork.freedesktop.org/patch/msgid/20210712085544.2828-1-thunder.leizhen@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/core/fbmem.c |   12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -965,13 +965,11 @@ fb_set_var(struct fb_info *info, struct
+               fb_var_to_videomode(&mode2, &info->var);
+               /* make sure we don't delete the videomode of current var */
+               ret = fb_mode_is_equal(&mode1, &mode2);
+-
+-              if (!ret)
+-                      fbcon_mode_deleted(info, &mode1);
+-
+-              if (!ret)
+-                      fb_delete_videomode(&mode1, &info->modelist);
+-
++              if (!ret) {
++                      ret = fbcon_mode_deleted(info, &mode1);
++                      if (!ret)
++                              fb_delete_videomode(&mode1, &info->modelist);
++              }
+               return ret ? -EINVAL : 0;
+       }
diff --git a/queue-5.4/scsi-core-fix-bad-pointer-dereference-when-ehandler-kthread-is-invalid.patch b/queue-5.4/scsi-core-fix-bad-pointer-dereference-when-ehandler-kthread-is-invalid.patch
new file mode 100644 (file)
index 0000000..3bfd8c2
--- /dev/null
@@ -0,0 +1,96 @@
+From 93aa71ad7379900e61c8adff6a710a4c18c7c99b Mon Sep 17 00:00:00 2001
+From: Tyrel Datwyler <tyreld@linux.ibm.com>
+Date: Thu, 1 Jul 2021 13:56:59 -0600
+Subject: scsi: core: Fix bad pointer dereference when ehandler kthread is invalid
+
+From: Tyrel Datwyler <tyreld@linux.ibm.com>
+
+commit 93aa71ad7379900e61c8adff6a710a4c18c7c99b upstream.
+
+Commit 66a834d09293 ("scsi: core: Fix error handling of scsi_host_alloc()")
+changed the allocation logic to call put_device() to perform host cleanup
+with the assumption that IDA removal and stopping the kthread would
+properly be performed in scsi_host_dev_release(). However, in the unlikely
+case that the error handler thread fails to spawn, shost->ehandler is set
+to ERR_PTR(-ENOMEM).
+
+The error handler cleanup code in scsi_host_dev_release() will call
+kthread_stop() if shost->ehandler != NULL which will always be the case
+whether the kthread was successfully spawned or not. In the case that it
+failed to spawn this has the nasty side effect of trying to dereference an
+invalid pointer when kthread_stop() is called. The following splat provides
+an example of this behavior in the wild:
+
+scsi host11: error handler thread failed to spawn, error = -4
+Kernel attempted to read user page (10c) - exploit attempt? (uid: 0)
+BUG: Kernel NULL pointer dereference on read at 0x0000010c
+Faulting instruction address: 0xc00000000818e9a8
+Oops: Kernel access of bad area, sig: 11 [#1]
+LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
+Modules linked in: ibmvscsi(+) scsi_transport_srp dm_multipath dm_mirror dm_region
+ hash dm_log dm_mod fuse overlay squashfs loop
+CPU: 12 PID: 274 Comm: systemd-udevd Not tainted 5.13.0-rc7 #1
+NIP:  c00000000818e9a8 LR: c0000000089846e8 CTR: 0000000000007ee8
+REGS: c000000037d12ea0 TRAP: 0300   Not tainted  (5.13.0-rc7)
+MSR:  800000000280b033 &lt;SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE&gt;  CR: 28228228
+XER: 20040001
+CFAR: c0000000089846e4 DAR: 000000000000010c DSISR: 40000000 IRQMASK: 0
+GPR00: c0000000089846e8 c000000037d13140 c000000009cc1100 fffffffffffffffc
+GPR04: 0000000000000001 0000000000000000 0000000000000000 c000000037dc0000
+GPR08: 0000000000000000 c000000037dc0000 0000000000000001 00000000fffff7ff
+GPR12: 0000000000008000 c00000000a049000 c000000037d13d00 000000011134d5a0
+GPR16: 0000000000001740 c0080000190d0000 c0080000190d1740 c000000009129288
+GPR20: c000000037d13bc0 0000000000000001 c000000037d13bc0 c0080000190b7898
+GPR24: c0080000190b7708 0000000000000000 c000000033bb2c48 0000000000000000
+GPR28: c000000046b28280 0000000000000000 000000000000010c fffffffffffffffc
+NIP [c00000000818e9a8] kthread_stop+0x38/0x230
+LR [c0000000089846e8] scsi_host_dev_release+0x98/0x160
+Call Trace:
+[c000000033bb2c48] 0xc000000033bb2c48 (unreliable)
+[c0000000089846e8] scsi_host_dev_release+0x98/0x160
+[c00000000891e960] device_release+0x60/0x100
+[c0000000087e55c4] kobject_release+0x84/0x210
+[c00000000891ec78] put_device+0x28/0x40
+[c000000008984ea4] scsi_host_alloc+0x314/0x430
+[c0080000190b38bc] ibmvscsi_probe+0x54/0xad0 [ibmvscsi]
+[c000000008110104] vio_bus_probe+0xa4/0x4b0
+[c00000000892a860] really_probe+0x140/0x680
+[c00000000892aefc] driver_probe_device+0x15c/0x200
+[c00000000892b63c] device_driver_attach+0xcc/0xe0
+[c00000000892b740] __driver_attach+0xf0/0x200
+[c000000008926f28] bus_for_each_dev+0xa8/0x130
+[c000000008929ce4] driver_attach+0x34/0x50
+[c000000008928fc0] bus_add_driver+0x1b0/0x300
+[c00000000892c798] driver_register+0x98/0x1a0
+[c00000000810eb60] __vio_register_driver+0x80/0xe0
+[c0080000190b4a30] ibmvscsi_module_init+0x9c/0xdc [ibmvscsi]
+[c0000000080121d0] do_one_initcall+0x60/0x2d0
+[c000000008261abc] do_init_module+0x7c/0x320
+[c000000008265700] load_module+0x2350/0x25b0
+[c000000008265cb4] __do_sys_finit_module+0xd4/0x160
+[c000000008031110] system_call_exception+0x150/0x2d0
+[c00000000800d35c] system_call_common+0xec/0x278
+
+Fix this be nulling shost->ehandler when the kthread fails to spawn.
+
+Link: https://lore.kernel.org/r/20210701195659.3185475-1-tyreld@linux.ibm.com
+Fixes: 66a834d09293 ("scsi: core: Fix error handling of scsi_host_alloc()")
+Cc: stable@vger.kernel.org
+Reviewed-by: Ming Lei <ming.lei@redhat.com>
+Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/scsi/hosts.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -486,6 +486,7 @@ struct Scsi_Host *scsi_host_alloc(struct
+               shost_printk(KERN_WARNING, shost,
+                       "error handler thread failed to spawn, error = %ld\n",
+                       PTR_ERR(shost->ehandler));
++              shost->ehandler = NULL;
+               goto fail;
+       }
index 5e5d13c4a680f21f7c65746560d01bba1b17b3cf..020f3021095452ddab10144fb660b856a9e556d4 100644 (file)
@@ -1,3 +1,7 @@
 kvm-mmio-fix-use-after-free-read-in-kvm_vm_ioctl_unregister_coalesced_mmio.patch
 kvm-x86-use-guest-maxphyaddr-from-cpuid.0x8000_0008-iff-tdp-is-enabled.patch
 kvm-x86-disable-hardware-breakpoints-unconditionally-before-kvm_x86-run.patch
+scsi-core-fix-bad-pointer-dereference-when-ehandler-kthread-is-invalid.patch
+tracing-do-not-reference-char-as-a-string-in-histograms.patch
+cgroup-verify-that-source-is-a-string.patch
+fbmem-do-not-delete-the-mode-that-is-still-in-use.patch
diff --git a/queue-5.4/tracing-do-not-reference-char-as-a-string-in-histograms.patch b/queue-5.4/tracing-do-not-reference-char-as-a-string-in-histograms.patch
new file mode 100644 (file)
index 0000000..1718d61
--- /dev/null
@@ -0,0 +1,105 @@
+From 704adfb5a9978462cd861f170201ae2b5e3d3a80 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Thu, 15 Jul 2021 00:02:06 -0400
+Subject: tracing: Do not reference char * as a string in histograms
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit 704adfb5a9978462cd861f170201ae2b5e3d3a80 upstream.
+
+The histogram logic was allowing events with char * pointers to be used as
+normal strings. But it was easy to crash the kernel with:
+
+ # echo 'hist:keys=filename' > events/syscalls/sys_enter_openat/trigger
+
+And open some files, and boom!
+
+ BUG: unable to handle page fault for address: 00007f2ced0c3280
+ #PF: supervisor read access in kernel mode
+ #PF: error_code(0x0000) - not-present page
+ PGD 1173fa067 P4D 1173fa067 PUD 1171b6067 PMD 1171dd067 PTE 0
+ Oops: 0000 [#1] PREEMPT SMP
+ CPU: 6 PID: 1810 Comm: cat Not tainted 5.13.0-rc5-test+ #61
+ Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01
+v03.03 07/14/2016
+ RIP: 0010:strlen+0x0/0x20
+ Code: f6 82 80 2a 0b a9 20 74 11 0f b6 50 01 48 83 c0 01 f6 82 80 2a 0b
+a9 20 75 ef c3 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 <80> 3f 00 74
+10 48 89 f8 48 83 c0 01 80 38 00 75 f7 48 29 f8 c3
+
+ RSP: 0018:ffffbdbf81567b50 EFLAGS: 00010246
+ RAX: 0000000000000003 RBX: ffff93815cdb3800 RCX: ffff9382401a22d0
+ RDX: 0000000000000100 RSI: 0000000000000000 RDI: 00007f2ced0c3280
+ RBP: 0000000000000100 R08: ffff9382409ff074 R09: ffffbdbf81567c98
+ R10: ffff9382409ff074 R11: 0000000000000000 R12: ffff9382409ff074
+ R13: 0000000000000001 R14: ffff93815a744f00 R15: 00007f2ced0c3280
+ FS:  00007f2ced0f8580(0000) GS:ffff93825a800000(0000)
+knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f2ced0c3280 CR3: 0000000107069005 CR4: 00000000001706e0
+ Call Trace:
+  event_hist_trigger+0x463/0x5f0
+  ? find_held_lock+0x32/0x90
+  ? sched_clock_cpu+0xe/0xd0
+  ? lock_release+0x155/0x440
+  ? kernel_init_free_pages+0x6d/0x90
+  ? preempt_count_sub+0x9b/0xd0
+  ? kernel_init_free_pages+0x6d/0x90
+  ? get_page_from_freelist+0x12c4/0x1680
+  ? __rb_reserve_next+0xe5/0x460
+  ? ring_buffer_lock_reserve+0x12a/0x3f0
+  event_triggers_call+0x52/0xe0
+  ftrace_syscall_enter+0x264/0x2c0
+  syscall_trace_enter.constprop.0+0x1ee/0x210
+  do_syscall_64+0x1c/0x80
+  entry_SYSCALL_64_after_hwframe+0x44/0xae
+
+Where it triggered a fault on strlen(key) where key was the filename.
+
+The reason is that filename is a char * to user space, and the histogram
+code just blindly dereferenced it, with obvious bad results.
+
+I originally tried to use strncpy_from_user/kernel_nofault() but found
+that there's other places that its dereferenced and not worth the effort.
+
+Just do not allow "char *" to act like strings.
+
+Link: https://lkml.kernel.org/r/20210715000206.025df9d2@rorschach.local.home
+
+Cc: Ingo Molnar <mingo@kernel.org>
+Cc: Andrew Morton <akpm@linux-foundation.org>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Tzvetomir Stoyanov <tz.stoyanov@gmail.com>
+Cc: stable@vger.kernel.org
+Acked-by: Namhyung Kim <namhyung@kernel.org>
+Acked-by: Tom Zanussi <zanussi@kernel.org>
+Fixes: 79e577cbce4c4 ("tracing: Support string type key properly")
+Fixes: 5967bd5c4239 ("tracing: Let filter_assign_type() detect FILTER_PTR_STRING")
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_events_hist.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/kernel/trace/trace_events_hist.c
++++ b/kernel/trace/trace_events_hist.c
+@@ -2571,7 +2571,9 @@ static struct hist_field *create_hist_fi
+       if (WARN_ON_ONCE(!field))
+               goto out;
+-      if (is_string_field(field)) {
++      /* Pointers to strings are just pointers and dangerous to dereference */
++      if (is_string_field(field) &&
++          (field->filter_type != FILTER_PTR_STRING)) {
+               flags |= HIST_FIELD_FL_STRING;
+               hist_field->size = MAX_FILTER_STR_VAL;
+@@ -5326,8 +5328,6 @@ static inline void add_to_key(char *comp
+               field = key_field->field;
+               if (field->filter_type == FILTER_DYN_STRING)
+                       size = *(u32 *)(rec + field->offset) >> 16;
+-              else if (field->filter_type == FILTER_PTR_STRING)
+-                      size = strlen(key);
+               else if (field->filter_type == FILTER_STATIC_STRING)
+                       size = field->size;