From: Greg Kroah-Hartman Date: Mon, 22 Mar 2021 09:27:29 +0000 (+0100) Subject: 4.19-stable patches X-Git-Tag: v4.4.263~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82672c4885944db6d6421d6a07f31c8d53964e8d;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches added patches: pci-rpadlpar-fix-potential-drc_name-corruption-in-store-functions.patch perf-x86-intel-fix-a-crash-caused-by-zero-pebs-status.patch x86-introduce-ts_compat_restart-to-fix-get_nr_restart_syscall.patch x86-ioapic-ignore-irq2-again.patch x86-move-ts_compat-back-to-asm-thread_info.h.patch --- diff --git a/queue-4.19/pci-rpadlpar-fix-potential-drc_name-corruption-in-store-functions.patch b/queue-4.19/pci-rpadlpar-fix-potential-drc_name-corruption-in-store-functions.patch new file mode 100644 index 00000000000..a0a142c547d --- /dev/null +++ b/queue-4.19/pci-rpadlpar-fix-potential-drc_name-corruption-in-store-functions.patch @@ -0,0 +1,83 @@ +From cc7a0bb058b85ea03db87169c60c7cfdd5d34678 Mon Sep 17 00:00:00 2001 +From: Tyrel Datwyler +Date: Mon, 15 Mar 2021 15:48:21 -0600 +Subject: PCI: rpadlpar: Fix potential drc_name corruption in store functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tyrel Datwyler + +commit cc7a0bb058b85ea03db87169c60c7cfdd5d34678 upstream. + +Both add_slot_store() and remove_slot_store() try to fix up the +drc_name copied from the store buffer by placing a NUL terminator at +nbyte + 1 or in place of a '\n' if present. However, the static buffer +that we copy the drc_name data into is not zeroed and can contain +anything past the n-th byte. + +This is problematic if a '\n' byte appears in that buffer after nbytes +and the string copied into the store buffer was not NUL terminated to +start with as the strchr() search for a '\n' byte will mark this +incorrectly as the end of the drc_name string resulting in a drc_name +string that contains garbage data after the n-th byte. + +Additionally it will cause us to overwrite that '\n' byte on the stack +with NUL, potentially corrupting data on the stack. + +The following debugging shows an example of the drmgr utility writing +"PHB 4543" to the add_slot sysfs attribute, but add_slot_store() +logging a corrupted string value. + + drmgr: drmgr: -c phb -a -s PHB 4543 -d 1 + add_slot_store: drc_name = PHB 4543°|<82>!, rc = -19 + +Fix this by using strscpy() instead of memcpy() to ensure the string +is NUL terminated when copied into the static drc_name buffer. +Further, since the string is now NUL terminated the code only needs to +change '\n' to '\0' when present. + +Cc: stable@vger.kernel.org +Signed-off-by: Tyrel Datwyler +[mpe: Reformat change log and add mention of possible stack corruption] +Signed-off-by: Michael Ellerman +Link: https://lore.kernel.org/r/20210315214821.452959-1-tyreld@linux.ibm.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/hotplug/rpadlpar_sysfs.c | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/drivers/pci/hotplug/rpadlpar_sysfs.c ++++ b/drivers/pci/hotplug/rpadlpar_sysfs.c +@@ -34,12 +34,11 @@ static ssize_t add_slot_store(struct kob + if (nbytes >= MAX_DRC_NAME_LEN) + return 0; + +- memcpy(drc_name, buf, nbytes); ++ strscpy(drc_name, buf, nbytes + 1); + + end = strchr(drc_name, '\n'); +- if (!end) +- end = &drc_name[nbytes]; +- *end = '\0'; ++ if (end) ++ *end = '\0'; + + rc = dlpar_add_slot(drc_name); + if (rc) +@@ -65,12 +64,11 @@ static ssize_t remove_slot_store(struct + if (nbytes >= MAX_DRC_NAME_LEN) + return 0; + +- memcpy(drc_name, buf, nbytes); ++ strscpy(drc_name, buf, nbytes + 1); + + end = strchr(drc_name, '\n'); +- if (!end) +- end = &drc_name[nbytes]; +- *end = '\0'; ++ if (end) ++ *end = '\0'; + + rc = dlpar_remove_slot(drc_name); + if (rc) diff --git a/queue-4.19/perf-x86-intel-fix-a-crash-caused-by-zero-pebs-status.patch b/queue-4.19/perf-x86-intel-fix-a-crash-caused-by-zero-pebs-status.patch new file mode 100644 index 00000000000..41703e36d70 --- /dev/null +++ b/queue-4.19/perf-x86-intel-fix-a-crash-caused-by-zero-pebs-status.patch @@ -0,0 +1,53 @@ +From d88d05a9e0b6d9356e97129d4ff9942d765f46ea Mon Sep 17 00:00:00 2001 +From: Kan Liang +Date: Fri, 12 Mar 2021 05:21:37 -0800 +Subject: perf/x86/intel: Fix a crash caused by zero PEBS status + +From: Kan Liang + +commit d88d05a9e0b6d9356e97129d4ff9942d765f46ea upstream. + +A repeatable crash can be triggered by the perf_fuzzer on some Haswell +system. +https://lore.kernel.org/lkml/7170d3b-c17f-1ded-52aa-cc6d9ae999f4@maine.edu/ + +For some old CPUs (HSW and earlier), the PEBS status in a PEBS record +may be mistakenly set to 0. To minimize the impact of the defect, the +commit was introduced to try to avoid dropping the PEBS record for some +cases. It adds a check in the intel_pmu_drain_pebs_nhm(), and updates +the local pebs_status accordingly. However, it doesn't correct the PEBS +status in the PEBS record, which may trigger the crash, especially for +the large PEBS. + +It's possible that all the PEBS records in a large PEBS have the PEBS +status 0. If so, the first get_next_pebs_record_by_bit() in the +__intel_pmu_pebs_event() returns NULL. The at = NULL. Since it's a large +PEBS, the 'count' parameter must > 1. The second +get_next_pebs_record_by_bit() will crash. + +Besides the local pebs_status, correct the PEBS status in the PEBS +record as well. + +Fixes: 01330d7288e0 ("perf/x86: Allow zero PEBS status with only single active event") +Reported-by: Vince Weaver +Suggested-by: Peter Zijlstra (Intel) +Signed-off-by: Kan Liang +Signed-off-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/1615555298-140216-1-git-send-email-kan.liang@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/events/intel/ds.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/events/intel/ds.c ++++ b/arch/x86/events/intel/ds.c +@@ -1557,7 +1557,7 @@ static void intel_pmu_drain_pebs_nhm(str + */ + if (!pebs_status && cpuc->pebs_enabled && + !(cpuc->pebs_enabled & (cpuc->pebs_enabled-1))) +- pebs_status = cpuc->pebs_enabled; ++ pebs_status = p->status = cpuc->pebs_enabled; + + bit = find_first_bit((unsigned long *)&pebs_status, + x86_pmu.max_pebs_events); diff --git a/queue-4.19/series b/queue-4.19/series index ca275737a91..aca3f495217 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -31,3 +31,8 @@ iio-gyro-mpu3050-fix-error-handling-in-mpu3050_trigger_handler.patch iio-hid-sensor-humidity-fix-alignment-issue-of-timestamp-channel.patch iio-hid-sensor-prox-fix-scale-not-correct-issue.patch iio-hid-sensor-temperature-fix-issues-of-timestamp-channel.patch +pci-rpadlpar-fix-potential-drc_name-corruption-in-store-functions.patch +perf-x86-intel-fix-a-crash-caused-by-zero-pebs-status.patch +x86-ioapic-ignore-irq2-again.patch +x86-move-ts_compat-back-to-asm-thread_info.h.patch +x86-introduce-ts_compat_restart-to-fix-get_nr_restart_syscall.patch diff --git a/queue-4.19/x86-introduce-ts_compat_restart-to-fix-get_nr_restart_syscall.patch b/queue-4.19/x86-introduce-ts_compat_restart-to-fix-get_nr_restart_syscall.patch new file mode 100644 index 00000000000..81c0e2ce925 --- /dev/null +++ b/queue-4.19/x86-introduce-ts_compat_restart-to-fix-get_nr_restart_syscall.patch @@ -0,0 +1,129 @@ +From 8c150ba2fb5995c84a7a43848250d444a3329a7d Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Mon, 1 Feb 2021 18:47:09 +0100 +Subject: x86: Introduce TS_COMPAT_RESTART to fix get_nr_restart_syscall() + +From: Oleg Nesterov + +commit 8c150ba2fb5995c84a7a43848250d444a3329a7d upstream. + +The comment in get_nr_restart_syscall() says: + + * The problem is that we can get here when ptrace pokes + * syscall-like values into regs even if we're not in a syscall + * at all. + +Yes, but if not in a syscall then the + + status & (TS_COMPAT|TS_I386_REGS_POKED) + +check below can't really help: + + - TS_COMPAT can't be set + + - TS_I386_REGS_POKED is only set if regs->orig_ax was changed by + 32bit debugger; and even in this case get_nr_restart_syscall() + is only correct if the tracee is 32bit too. + +Suppose that a 64bit debugger plays with a 32bit tracee and + + * Tracee calls sleep(2) // TS_COMPAT is set + * User interrupts the tracee by CTRL-C after 1 sec and does + "(gdb) call func()" + * gdb saves the regs by PTRACE_GETREGS + * does PTRACE_SETREGS to set %rip='func' and %orig_rax=-1 + * PTRACE_CONT // TS_COMPAT is cleared + * func() hits int3. + * Debugger catches SIGTRAP. + * Restore original regs by PTRACE_SETREGS. + * PTRACE_CONT + +get_nr_restart_syscall() wrongly returns __NR_restart_syscall==219, the +tracee calls ia32_sys_call_table[219] == sys_madvise. + +Add the sticky TS_COMPAT_RESTART flag which survives after return to user +mode. It's going to be removed in the next step again by storing the +information in the restart block. As a further cleanup it might be possible +to remove also TS_I386_REGS_POKED with that. + +Test-case: + + $ cvs -d :pserver:anoncvs:anoncvs@sourceware.org:/cvs/systemtap co ptrace-tests + $ gcc -o erestartsys-trap-debuggee ptrace-tests/tests/erestartsys-trap-debuggee.c --m32 + $ gcc -o erestartsys-trap-debugger ptrace-tests/tests/erestartsys-trap-debugger.c -lutil + $ ./erestartsys-trap-debugger + Unexpected: retval 1, errno 22 + erestartsys-trap-debugger: ptrace-tests/tests/erestartsys-trap-debugger.c:421 + +Fixes: 609c19a385c8 ("x86/ptrace: Stop setting TS_COMPAT in ptrace code") +Reported-by: Jan Kratochvil +Signed-off-by: Oleg Nesterov +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20210201174709.GA17895@redhat.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/thread_info.h | 14 +++++++++++++- + arch/x86/kernel/signal.c | 24 +----------------------- + 2 files changed, 14 insertions(+), 24 deletions(-) + +--- a/arch/x86/include/asm/thread_info.h ++++ b/arch/x86/include/asm/thread_info.h +@@ -236,10 +236,22 @@ static inline int arch_within_stack_fram + */ + #define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ + ++#ifndef __ASSEMBLY__ + #ifdef CONFIG_COMPAT + #define TS_I386_REGS_POKED 0x0004 /* regs poked by 32-bit ptracer */ ++#define TS_COMPAT_RESTART 0x0008 ++ ++#define arch_set_restart_data arch_set_restart_data ++ ++static inline void arch_set_restart_data(struct restart_block *restart) ++{ ++ struct thread_info *ti = current_thread_info(); ++ if (ti->status & TS_COMPAT) ++ ti->status |= TS_COMPAT_RESTART; ++ else ++ ti->status &= ~TS_COMPAT_RESTART; ++} + #endif +-#ifndef __ASSEMBLY__ + + #ifdef CONFIG_X86_32 + #define in_ia32_syscall() true +--- a/arch/x86/kernel/signal.c ++++ b/arch/x86/kernel/signal.c +@@ -776,30 +776,8 @@ handle_signal(struct ksignal *ksig, stru + + static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs) + { +- /* +- * This function is fundamentally broken as currently +- * implemented. +- * +- * The idea is that we want to trigger a call to the +- * restart_block() syscall and that we want in_ia32_syscall(), +- * in_x32_syscall(), etc. to match whatever they were in the +- * syscall being restarted. We assume that the syscall +- * instruction at (regs->ip - 2) matches whatever syscall +- * instruction we used to enter in the first place. +- * +- * The problem is that we can get here when ptrace pokes +- * syscall-like values into regs even if we're not in a syscall +- * at all. +- * +- * For now, we maintain historical behavior and guess based on +- * stored state. We could do better by saving the actual +- * syscall arch in restart_block or (with caveats on x32) by +- * checking if regs->ip points to 'int $0x80'. The current +- * behavior is incorrect if a tracer has a different bitness +- * than the tracee. +- */ + #ifdef CONFIG_IA32_EMULATION +- if (current_thread_info()->status & (TS_COMPAT|TS_I386_REGS_POKED)) ++ if (current_thread_info()->status & TS_COMPAT_RESTART) + return __NR_ia32_restart_syscall; + #endif + #ifdef CONFIG_X86_X32_ABI diff --git a/queue-4.19/x86-ioapic-ignore-irq2-again.patch b/queue-4.19/x86-ioapic-ignore-irq2-again.patch new file mode 100644 index 00000000000..a785818dadf --- /dev/null +++ b/queue-4.19/x86-ioapic-ignore-irq2-again.patch @@ -0,0 +1,69 @@ +From a501b048a95b79e1e34f03cac3c87ff1e9f229ad Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Thu, 18 Mar 2021 20:26:47 +0100 +Subject: x86/ioapic: Ignore IRQ2 again + +From: Thomas Gleixner + +commit a501b048a95b79e1e34f03cac3c87ff1e9f229ad upstream. + +Vitaly ran into an issue with hotplugging CPU0 on an Amazon instance where +the matrix allocator claimed to be out of vectors. He analyzed it down to +the point that IRQ2, the PIC cascade interrupt, which is supposed to be not +ever routed to the IO/APIC ended up having an interrupt vector assigned +which got moved during unplug of CPU0. + +The underlying issue is that IRQ2 for various reasons (see commit +af174783b925 ("x86: I/O APIC: Never configure IRQ2" for details) is treated +as a reserved system vector by the vector core code and is not accounted as +a regular vector. The Amazon BIOS has an routing entry of pin2 to IRQ2 +which causes the IO/APIC setup to claim that interrupt which is granted by +the vector domain because there is no sanity check. As a consequence the +allocation counter of CPU0 underflows which causes a subsequent unplug to +fail with: + + [ ... ] CPU 0 has 4294967295 vectors, 589 available. Cannot disable CPU + +There is another sanity check missing in the matrix allocator, but the +underlying root cause is that the IO/APIC code lost the IRQ2 ignore logic +during the conversion to irqdomains. + +For almost 6 years nobody complained about this wreckage, which might +indicate that this requirement could be lifted, but for any system which +actually has a PIC IRQ2 is unusable by design so any routing entry has no +effect and the interrupt cannot be connected to a device anyway. + +Due to that and due to history biased paranoia reasons restore the IRQ2 +ignore logic and treat it as non existent despite a routing entry claiming +otherwise. + +Fixes: d32932d02e18 ("x86/irq: Convert IOAPIC to use hierarchical irqdomain interfaces") +Reported-by: Vitaly Kuznetsov +Signed-off-by: Thomas Gleixner +Tested-by: Vitaly Kuznetsov +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20210318192819.636943062@linutronix.de +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/apic/io_apic.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/arch/x86/kernel/apic/io_apic.c ++++ b/arch/x86/kernel/apic/io_apic.c +@@ -1043,6 +1043,16 @@ static int mp_map_pin_to_irq(u32 gsi, in + if (idx >= 0 && test_bit(mp_irqs[idx].srcbus, mp_bus_not_pci)) { + irq = mp_irqs[idx].srcbusirq; + legacy = mp_is_legacy_irq(irq); ++ /* ++ * IRQ2 is unusable for historical reasons on systems which ++ * have a legacy PIC. See the comment vs. IRQ2 further down. ++ * ++ * If this gets removed at some point then the related code ++ * in lapic_assign_system_vectors() needs to be adjusted as ++ * well. ++ */ ++ if (legacy && irq == PIC_CASCADE_IR) ++ return -EINVAL; + } + + mutex_lock(&ioapic_mutex); diff --git a/queue-4.19/x86-move-ts_compat-back-to-asm-thread_info.h.patch b/queue-4.19/x86-move-ts_compat-back-to-asm-thread_info.h.patch new file mode 100644 index 00000000000..eee974c8f65 --- /dev/null +++ b/queue-4.19/x86-move-ts_compat-back-to-asm-thread_info.h.patch @@ -0,0 +1,65 @@ +From 66c1b6d74cd7035e85c426f0af4aede19e805c8a Mon Sep 17 00:00:00 2001 +From: Oleg Nesterov +Date: Mon, 1 Feb 2021 18:46:49 +0100 +Subject: x86: Move TS_COMPAT back to asm/thread_info.h + +From: Oleg Nesterov + +commit 66c1b6d74cd7035e85c426f0af4aede19e805c8a upstream. + +Move TS_COMPAT back to asm/thread_info.h, close to TS_I386_REGS_POKED. + +It was moved to asm/processor.h by b9d989c7218a ("x86/asm: Move the +thread_info::status field to thread_struct"), then later 37a8f7c38339 +("x86/asm: Move 'status' from thread_struct to thread_info") moved the +'status' field back but TS_COMPAT was forgotten. + +Preparatory patch to fix the COMPAT case for get_nr_restart_syscall() + +Fixes: 609c19a385c8 ("x86/ptrace: Stop setting TS_COMPAT in ptrace code") +Signed-off-by: Oleg Nesterov +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20210201174649.GA17880@redhat.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/processor.h | 9 --------- + arch/x86/include/asm/thread_info.h | 9 +++++++++ + 2 files changed, 9 insertions(+), 9 deletions(-) + +--- a/arch/x86/include/asm/processor.h ++++ b/arch/x86/include/asm/processor.h +@@ -522,15 +522,6 @@ static inline void arch_thread_struct_wh + } + + /* +- * Thread-synchronous status. +- * +- * This is different from the flags in that nobody else +- * ever touches our thread-synchronous status, so we don't +- * have to worry about atomic accesses. +- */ +-#define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ +- +-/* + * Set IOPL bits in EFLAGS from given mask + */ + static inline void native_set_iopl_mask(unsigned mask) +--- a/arch/x86/include/asm/thread_info.h ++++ b/arch/x86/include/asm/thread_info.h +@@ -227,6 +227,15 @@ static inline int arch_within_stack_fram + + #endif + ++/* ++ * Thread-synchronous status. ++ * ++ * This is different from the flags in that nobody else ++ * ever touches our thread-synchronous status, so we don't ++ * have to worry about atomic accesses. ++ */ ++#define TS_COMPAT 0x0002 /* 32bit syscall active (64BIT)*/ ++ + #ifdef CONFIG_COMPAT + #define TS_I386_REGS_POKED 0x0004 /* regs poked by 32-bit ptracer */ + #endif