From: Greg Kroah-Hartman Date: Tue, 17 Nov 2020 11:56:48 +0000 (+0100) Subject: 4.14-stable patches X-Git-Tag: v4.4.244~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fcc7d3f3c78b1741cd0fa36283f2339ccea0018d;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: perf-core-fix-race-in-the-perf_mmap_close-function.patch reboot-fix-overflow-parsing-reboot-cpu-number.patch revert-kernel-reboot.c-convert-simple_strtoul-to-kstrtoint.patch --- diff --git a/queue-4.14/perf-core-fix-race-in-the-perf_mmap_close-function.patch b/queue-4.14/perf-core-fix-race-in-the-perf_mmap_close-function.patch new file mode 100644 index 00000000000..1b74da71ce3 --- /dev/null +++ b/queue-4.14/perf-core-fix-race-in-the-perf_mmap_close-function.patch @@ -0,0 +1,100 @@ +From f91072ed1b7283b13ca57fcfbece5a3b92726143 Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Wed, 16 Sep 2020 13:53:11 +0200 +Subject: perf/core: Fix race in the perf_mmap_close() function + +From: Jiri Olsa + +commit f91072ed1b7283b13ca57fcfbece5a3b92726143 upstream. + +There's a possible race in perf_mmap_close() when checking ring buffer's +mmap_count refcount value. The problem is that the mmap_count check is +not atomic because we call atomic_dec() and atomic_read() separately. + + perf_mmap_close: + ... + atomic_dec(&rb->mmap_count); + ... + if (atomic_read(&rb->mmap_count)) + goto out_put; + + + free_uid + +out_put: + ring_buffer_put(rb); /* could be last */ + +The race can happen when we have two (or more) events sharing same ring +buffer and they go through atomic_dec() and then they both see 0 as refcount +value later in atomic_read(). Then both will go on and execute code which +is meant to be run just once. + +The code that detaches ring buffer is probably fine to be executed more +than once, but the problem is in calling free_uid(), which will later on +demonstrate in related crashes and refcount warnings, like: + + refcount_t: addition on 0; use-after-free. + ... + RIP: 0010:refcount_warn_saturate+0x6d/0xf + ... + Call Trace: + prepare_creds+0x190/0x1e0 + copy_creds+0x35/0x172 + copy_process+0x471/0x1a80 + _do_fork+0x83/0x3a0 + __do_sys_wait4+0x83/0x90 + __do_sys_clone+0x85/0xa0 + do_syscall_64+0x5b/0x1e0 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +Using atomic decrease and check instead of separated calls. + +Tested-by: Michael Petlan +Signed-off-by: Jiri Olsa +Signed-off-by: Ingo Molnar +Acked-by: Peter Zijlstra +Acked-by: Namhyung Kim +Acked-by: Wade Mealing +Fixes: 9bb5d40cd93c ("perf: Fix mmap() accounting hole"); +Link: https://lore.kernel.org/r/20200916115311.GE2301783@krava +[sudip: used ring_buffer] +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + kernel/events/core.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -5207,11 +5207,11 @@ static void perf_pmu_output_stop(struct + static void perf_mmap_close(struct vm_area_struct *vma) + { + struct perf_event *event = vma->vm_file->private_data; +- + struct ring_buffer *rb = ring_buffer_get(event); + struct user_struct *mmap_user = rb->mmap_user; + int mmap_locked = rb->mmap_locked; + unsigned long size = perf_data_size(rb); ++ bool detach_rest = false; + + if (event->pmu->event_unmapped) + event->pmu->event_unmapped(event, vma->vm_mm); +@@ -5242,7 +5242,8 @@ static void perf_mmap_close(struct vm_ar + mutex_unlock(&event->mmap_mutex); + } + +- atomic_dec(&rb->mmap_count); ++ if (atomic_dec_and_test(&rb->mmap_count)) ++ detach_rest = true; + + if (!atomic_dec_and_mutex_lock(&event->mmap_count, &event->mmap_mutex)) + goto out_put; +@@ -5251,7 +5252,7 @@ static void perf_mmap_close(struct vm_ar + mutex_unlock(&event->mmap_mutex); + + /* If there's still other mmap()s of this buffer, we're done. */ +- if (atomic_read(&rb->mmap_count)) ++ if (!detach_rest) + goto out_put; + + /* diff --git a/queue-4.14/reboot-fix-overflow-parsing-reboot-cpu-number.patch b/queue-4.14/reboot-fix-overflow-parsing-reboot-cpu-number.patch new file mode 100644 index 00000000000..66016e4d242 --- /dev/null +++ b/queue-4.14/reboot-fix-overflow-parsing-reboot-cpu-number.patch @@ -0,0 +1,75 @@ +From df5b0ab3e08a156701b537809914b339b0daa526 Mon Sep 17 00:00:00 2001 +From: Matteo Croce +Date: Fri, 13 Nov 2020 22:52:07 -0800 +Subject: reboot: fix overflow parsing reboot cpu number + +From: Matteo Croce + +commit df5b0ab3e08a156701b537809914b339b0daa526 upstream. + +Limit the CPU number to num_possible_cpus(), because setting it to a +value lower than INT_MAX but higher than NR_CPUS produces the following +error on reboot and shutdown: + + BUG: unable to handle page fault for address: ffffffff90ab1bb0 + #PF: supervisor read access in kernel mode + #PF: error_code(0x0000) - not-present page + PGD 1c09067 P4D 1c09067 PUD 1c0a063 PMD 0 + Oops: 0000 [#1] SMP + CPU: 1 PID: 1 Comm: systemd-shutdow Not tainted 5.9.0-rc8-kvm #110 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.13.0-2.fc32 04/01/2014 + RIP: 0010:migrate_to_reboot_cpu+0xe/0x60 + Code: ea ea 00 48 89 fa 48 c7 c7 30 57 f1 81 e9 fa ef ff ff 66 2e 0f 1f 84 00 00 00 00 00 53 8b 1d d5 ea ea 00 e8 14 33 fe ff 89 da <48> 0f a3 15 ea fc bd 00 48 89 d0 73 29 89 c2 c1 e8 06 65 48 8b 3c + RSP: 0018:ffffc90000013e08 EFLAGS: 00010246 + RAX: ffff88801f0a0000 RBX: 0000000077359400 RCX: 0000000000000000 + RDX: 0000000077359400 RSI: 0000000000000002 RDI: ffffffff81c199e0 + RBP: ffffffff81c1e3c0 R08: ffff88801f41f000 R09: ffffffff81c1e348 + R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 + R13: 00007f32bedf8830 R14: 00000000fee1dead R15: 0000000000000000 + FS: 00007f32bedf8980(0000) GS:ffff88801f480000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: ffffffff90ab1bb0 CR3: 000000001d057000 CR4: 00000000000006a0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + Call Trace: + __do_sys_reboot.cold+0x34/0x5b + do_syscall_64+0x2d/0x40 + +Fixes: 1b3a5d02ee07 ("reboot: move arch/x86 reboot= handling to generic kernel") +Signed-off-by: Matteo Croce +Signed-off-by: Andrew Morton +Cc: Arnd Bergmann +Cc: Fabian Frederick +Cc: Greg Kroah-Hartman +Cc: Guenter Roeck +Cc: Kees Cook +Cc: Mike Rapoport +Cc: Pavel Tatashin +Cc: Petr Mladek +Cc: Robin Holt +Cc: +Link: https://lkml.kernel.org/r/20201103214025.116799-3-mcroce@linux.microsoft.com +Signed-off-by: Linus Torvalds +[sudip: use reboot_mode instead of mode] +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + kernel/reboot.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/kernel/reboot.c ++++ b/kernel/reboot.c +@@ -519,6 +519,13 @@ static int __init reboot_setup(char *str + reboot_cpu = simple_strtoul(str+3, NULL, 0); + else + reboot_mode = REBOOT_SOFT; ++ if (reboot_cpu >= num_possible_cpus()) { ++ pr_err("Ignoring the CPU number in reboot= option. " ++ "CPU %d exceeds possible cpu number %d\n", ++ reboot_cpu, num_possible_cpus()); ++ reboot_cpu = 0; ++ break; ++ } + break; + + case 'g': diff --git a/queue-4.14/revert-kernel-reboot.c-convert-simple_strtoul-to-kstrtoint.patch b/queue-4.14/revert-kernel-reboot.c-convert-simple_strtoul-to-kstrtoint.patch new file mode 100644 index 00000000000..1d8911afc6f --- /dev/null +++ b/queue-4.14/revert-kernel-reboot.c-convert-simple_strtoul-to-kstrtoint.patch @@ -0,0 +1,87 @@ +From 8b92c4ff4423aa9900cf838d3294fcade4dbda35 Mon Sep 17 00:00:00 2001 +From: Matteo Croce +Date: Fri, 13 Nov 2020 22:52:02 -0800 +Subject: Revert "kernel/reboot.c: convert simple_strtoul to kstrtoint" + +From: Matteo Croce + +commit 8b92c4ff4423aa9900cf838d3294fcade4dbda35 upstream. + +Patch series "fix parsing of reboot= cmdline", v3. + +The parsing of the reboot= cmdline has two major errors: + + - a missing bound check can crash the system on reboot + + - parsing of the cpu number only works if specified last + +Fix both. + +This patch (of 2): + +This reverts commit 616feab753972b97. + +kstrtoint() and simple_strtoul() have a subtle difference which makes +them non interchangeable: if a non digit character is found amid the +parsing, the former will return an error, while the latter will just +stop parsing, e.g. simple_strtoul("123xyx") = 123. + +The kernel cmdline reboot= argument allows to specify the CPU used for +rebooting, with the syntax `s####` among the other flags, e.g. +"reboot=warm,s31,force", so if this flag is not the last given, it's +silently ignored as well as the subsequent ones. + +Fixes: 616feab75397 ("kernel/reboot.c: convert simple_strtoul to kstrtoint") +Signed-off-by: Matteo Croce +Signed-off-by: Andrew Morton +Cc: Guenter Roeck +Cc: Petr Mladek +Cc: Arnd Bergmann +Cc: Mike Rapoport +Cc: Kees Cook +Cc: Pavel Tatashin +Cc: Robin Holt +Cc: Fabian Frederick +Cc: Greg Kroah-Hartman +Cc: +Link: https://lkml.kernel.org/r/20201103214025.116799-2-mcroce@linux.microsoft.com +Signed-off-by: Linus Torvalds +[sudip: use reboot_mode instead of mode] +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + kernel/reboot.c | 21 +++++++-------------- + 1 file changed, 7 insertions(+), 14 deletions(-) + +--- a/kernel/reboot.c ++++ b/kernel/reboot.c +@@ -512,22 +512,15 @@ static int __init reboot_setup(char *str + break; + + case 's': +- { +- int rc; +- +- if (isdigit(*(str+1))) { +- rc = kstrtoint(str+1, 0, &reboot_cpu); +- if (rc) +- return rc; +- } else if (str[1] == 'm' && str[2] == 'p' && +- isdigit(*(str+3))) { +- rc = kstrtoint(str+3, 0, &reboot_cpu); +- if (rc) +- return rc; +- } else ++ if (isdigit(*(str+1))) ++ reboot_cpu = simple_strtoul(str+1, NULL, 0); ++ else if (str[1] == 'm' && str[2] == 'p' && ++ isdigit(*(str+3))) ++ reboot_cpu = simple_strtoul(str+3, NULL, 0); ++ else + reboot_mode = REBOOT_SOFT; + break; +- } ++ + case 'g': + reboot_mode = REBOOT_GPIO; + break; diff --git a/queue-4.14/series b/queue-4.14/series index 200a96501ca..4f812c9e59d 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -79,3 +79,6 @@ xen-events-switch-user-event-channels-to-lateeoi-model.patch xen-events-use-a-common-cpu-hotplug-hook-for-event-channels.patch xen-events-defer-eoi-in-case-of-excessive-number-of-events.patch xen-events-block-rogue-events-for-some-time.patch +perf-core-fix-race-in-the-perf_mmap_close-function.patch +revert-kernel-reboot.c-convert-simple_strtoul-to-kstrtoint.patch +reboot-fix-overflow-parsing-reboot-cpu-number.patch