From: Greg Kroah-Hartman Date: Mon, 18 Feb 2019 12:05:17 +0000 (+0100) Subject: 3.18-stable patches X-Git-Tag: v3.18.135~17 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8249a222b63c4355a6e8f811cd1e965e39ec1f8b;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: alpha-fix-eiger-nr_irqs-to-128.patch alpha-fix-page-fault-handling-for-r16-r18-targets.patch signal-restore-the-stop-ptrace_event_exit.patch tracing-uprobes-fix-output-for-multiple-string-arguments.patch x86-a.out-clear-the-dump-structure-initially.patch --- diff --git a/queue-3.18/alpha-fix-eiger-nr_irqs-to-128.patch b/queue-3.18/alpha-fix-eiger-nr_irqs-to-128.patch new file mode 100644 index 00000000000..77413bb0489 --- /dev/null +++ b/queue-3.18/alpha-fix-eiger-nr_irqs-to-128.patch @@ -0,0 +1,51 @@ +From bfc913682464f45bc4d6044084e370f9048de9d5 Mon Sep 17 00:00:00 2001 +From: Meelis Roos +Date: Fri, 12 Oct 2018 12:27:51 +0300 +Subject: alpha: Fix Eiger NR_IRQS to 128 + +From: Meelis Roos + +commit bfc913682464f45bc4d6044084e370f9048de9d5 upstream. + +Eiger machine vector definition has nr_irqs 128, and working 2.6.26 +boot shows SCSI getting IRQ-s 64 and 65. Current kernel boot fails +because Symbios SCSI fails to request IRQ-s and does not find the disks. +It has been broken at least since 3.18 - the earliest I could test with +my gcc-5. + +The headers have moved around and possibly another order of defines has +worked in the past - but since 128 seems to be correct and used, fix +arch/alpha/include/asm/irq.h to have NR_IRQS=128 for Eiger. + +This fixes 4.19-rc7 boot on my Force Flexor A264 (Eiger subarch). + +Cc: stable@vger.kernel.org # v3.18+ +Signed-off-by: Meelis Roos +Signed-off-by: Matt Turner +Signed-off-by: Greg Kroah-Hartman + +--- + arch/alpha/include/asm/irq.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/arch/alpha/include/asm/irq.h ++++ b/arch/alpha/include/asm/irq.h +@@ -55,15 +55,15 @@ + + #elif defined(CONFIG_ALPHA_DP264) || \ + defined(CONFIG_ALPHA_LYNX) || \ +- defined(CONFIG_ALPHA_SHARK) || \ +- defined(CONFIG_ALPHA_EIGER) ++ defined(CONFIG_ALPHA_SHARK) + # define NR_IRQS 64 + + #elif defined(CONFIG_ALPHA_TITAN) + #define NR_IRQS 80 + + #elif defined(CONFIG_ALPHA_RAWHIDE) || \ +- defined(CONFIG_ALPHA_TAKARA) ++ defined(CONFIG_ALPHA_TAKARA) || \ ++ defined(CONFIG_ALPHA_EIGER) + # define NR_IRQS 128 + + #elif defined(CONFIG_ALPHA_WILDFIRE) diff --git a/queue-3.18/alpha-fix-page-fault-handling-for-r16-r18-targets.patch b/queue-3.18/alpha-fix-page-fault-handling-for-r16-r18-targets.patch new file mode 100644 index 00000000000..8dd6245ebdd --- /dev/null +++ b/queue-3.18/alpha-fix-page-fault-handling-for-r16-r18-targets.patch @@ -0,0 +1,118 @@ +From 491af60ffb848b59e82f7c9145833222e0bf27a5 Mon Sep 17 00:00:00 2001 +From: Sergei Trofimovich +Date: Mon, 31 Dec 2018 11:53:55 +0000 +Subject: alpha: fix page fault handling for r16-r18 targets + +From: Sergei Trofimovich + +commit 491af60ffb848b59e82f7c9145833222e0bf27a5 upstream. + +Fix page fault handling code to fixup r16-r18 registers. +Before the patch code had off-by-two registers bug. +This bug caused overwriting of ps,pc,gp registers instead +of fixing intended r16,r17,r18 (see `struct pt_regs`). + +More details: + +Initially Dmitry noticed a kernel bug as a failure +on strace test suite. Test passes unmapped userspace +pointer to io_submit: + +```c + #include + #include + #include + #include + int main(void) + { + unsigned long ctx = 0; + if (syscall(__NR_io_setup, 1, &ctx)) + err(1, "io_setup"); + const size_t page_size = sysconf(_SC_PAGESIZE); + const size_t size = page_size * 2; + void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (MAP_FAILED == ptr) + err(1, "mmap(%zu)", size); + if (munmap(ptr, size)) + err(1, "munmap"); + syscall(__NR_io_submit, ctx, 1, ptr + page_size); + syscall(__NR_io_destroy, ctx); + return 0; + } +``` + +Running this test causes kernel to crash when handling page fault: + +``` + Unable to handle kernel paging request at virtual address ffffffffffff9468 + CPU 3 + aio(26027): Oops 0 + pc = [] ra = [] ps = 0000 Not tainted + pc is at sys_io_submit+0x108/0x200 + ra is at sys_io_submit+0x6c/0x200 + v0 = fffffc00c58e6300 t0 = fffffffffffffff2 t1 = 000002000025e000 + t2 = fffffc01f159fef8 t3 = fffffc0001009640 t4 = fffffc0000e0f6e0 + t5 = 0000020001002e9e t6 = 4c41564e49452031 t7 = fffffc01f159c000 + s0 = 0000000000000002 s1 = 000002000025e000 s2 = 0000000000000000 + s3 = 0000000000000000 s4 = 0000000000000000 s5 = fffffffffffffff2 + s6 = fffffc00c58e6300 + a0 = fffffc00c58e6300 a1 = 0000000000000000 a2 = 000002000025e000 + a3 = 00000200001ac260 a4 = 00000200001ac1e8 a5 = 0000000000000001 + t8 = 0000000000000008 t9 = 000000011f8bce30 t10= 00000200001ac440 + t11= 0000000000000000 pv = fffffc00006fd320 at = 0000000000000000 + gp = 0000000000000000 sp = 00000000265fd174 + Disabling lock debugging due to kernel taint + Trace: + [] entSys+0xa4/0xc0 +``` + +Here `gp` has invalid value. `gp is s overwritten by a fixup for the +following page fault handler in `io_submit` syscall handler: + +``` + __se_sys_io_submit + ... + ldq a1,0(t1) + bne t0,4280 <__se_sys_io_submit+0x180> +``` + +After a page fault `t0` should contain -EFALUT and `a1` is 0. +Instead `gp` was overwritten in place of `a1`. + +This happens due to a off-by-two bug in `dpf_reg()` for `r16-r18` +(aka `a0-a2`). + +I think the bug went unnoticed for a long time as `gp` is one +of scratch registers. Any kernel function call would re-calculate `gp`. + +Dmitry tracked down the bug origin back to 2.1.32 kernel version +where trap_a{0,1,2} fields were inserted into struct pt_regs. +And even before that `dpf_reg()` contained off-by-one error. + +Cc: Richard Henderson +Cc: Ivan Kokshaysky +Cc: linux-alpha@vger.kernel.org +Cc: linux-kernel@vger.kernel.org +Reported-and-reviewed-by: "Dmitry V. Levin" +Cc: stable@vger.kernel.org # v2.1.32+ +Bug: https://bugs.gentoo.org/672040 +Signed-off-by: Sergei Trofimovich +Signed-off-by: Matt Turner +Signed-off-by: Greg Kroah-Hartman + +--- + arch/alpha/mm/fault.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/alpha/mm/fault.c ++++ b/arch/alpha/mm/fault.c +@@ -78,7 +78,7 @@ __load_new_mm_context(struct mm_struct * + /* Macro for exception fixup code to access integer registers. */ + #define dpf_reg(r) \ + (((unsigned long *)regs)[(r) <= 8 ? (r) : (r) <= 15 ? (r)-16 : \ +- (r) <= 18 ? (r)+8 : (r)-10]) ++ (r) <= 18 ? (r)+10 : (r)-10]) + + asmlinkage void + do_page_fault(unsigned long address, unsigned long mmcsr, diff --git a/queue-3.18/series b/queue-3.18/series index d87608dd586..a72228070c9 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -97,3 +97,8 @@ perf-core-fix-impossible-ring-buffer-sizes-warning.patch alsa-usb-audio-fix-implicit-fb-endpoint-setup-by-quirk.patch input-bma150-register-input-device-after-setting-private-data.patch input-elantech-enable-3rd-button-support-on-fujitsu-celsius-h780.patch +alpha-fix-page-fault-handling-for-r16-r18-targets.patch +alpha-fix-eiger-nr_irqs-to-128.patch +tracing-uprobes-fix-output-for-multiple-string-arguments.patch +signal-restore-the-stop-ptrace_event_exit.patch +x86-a.out-clear-the-dump-structure-initially.patch diff --git a/queue-3.18/signal-restore-the-stop-ptrace_event_exit.patch b/queue-3.18/signal-restore-the-stop-ptrace_event_exit.patch new file mode 100644 index 00000000000..d2476bb15b0 --- /dev/null +++ b/queue-3.18/signal-restore-the-stop-ptrace_event_exit.patch @@ -0,0 +1,58 @@ +From cf43a757fd49442bc38f76088b70c2299eed2c2f Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Mon, 11 Feb 2019 23:27:42 -0600 +Subject: signal: Restore the stop PTRACE_EVENT_EXIT + +From: Eric W. Biederman + +commit cf43a757fd49442bc38f76088b70c2299eed2c2f upstream. + +In the middle of do_exit() there is there is a call +"ptrace_event(PTRACE_EVENT_EXIT, code);" That call places the process +in TACKED_TRACED aka "(TASK_WAKEKILL | __TASK_TRACED)" and waits for +for the debugger to release the task or SIGKILL to be delivered. + +Skipping past dequeue_signal when we know a fatal signal has already +been delivered resulted in SIGKILL remaining pending and +TIF_SIGPENDING remaining set. This in turn caused the +scheduler to not sleep in PTACE_EVENT_EXIT as it figured +a fatal signal was pending. This also caused ptrace_freeze_traced +in ptrace_check_attach to fail because it left a per thread +SIGKILL pending which is what fatal_signal_pending tests for. + +This difference in signal state caused strace to report +strace: Exit of unknown pid NNNNN ignored + +Therefore update the signal handling state like dequeue_signal +would when removing a per thread SIGKILL, by removing SIGKILL +from the per thread signal mask and clearing TIF_SIGPENDING. + +Acked-by: Oleg Nesterov +Reported-by: Oleg Nesterov +Reported-by: Ivan Delalande +Cc: stable@vger.kernel.org +Fixes: 35634ffa1751 ("signal: Always notice exiting tasks") +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/signal.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -2284,9 +2284,12 @@ relock: + } + + /* Has this task already been marked for death? */ +- ksig->info.si_signo = signr = SIGKILL; +- if (signal_group_exit(signal)) ++ if (signal_group_exit(signal)) { ++ ksig->info.si_signo = signr = SIGKILL; ++ sigdelset(¤t->pending.signal, SIGKILL); ++ recalc_sigpending(); + goto fatal; ++ } + + for (;;) { + struct k_sigaction *ka; diff --git a/queue-3.18/tracing-uprobes-fix-output-for-multiple-string-arguments.patch b/queue-3.18/tracing-uprobes-fix-output-for-multiple-string-arguments.patch new file mode 100644 index 00000000000..6545f96da2b --- /dev/null +++ b/queue-3.18/tracing-uprobes-fix-output-for-multiple-string-arguments.patch @@ -0,0 +1,79 @@ +From 0722069a5374b904ec1a67f91249f90e1cfae259 Mon Sep 17 00:00:00 2001 +From: Andreas Ziegler +Date: Wed, 16 Jan 2019 15:16:29 +0100 +Subject: tracing/uprobes: Fix output for multiple string arguments + +From: Andreas Ziegler + +commit 0722069a5374b904ec1a67f91249f90e1cfae259 upstream. + +When printing multiple uprobe arguments as strings the output for the +earlier arguments would also include all later string arguments. + +This is best explained in an example: + +Consider adding a uprobe to a function receiving two strings as +parameters which is at offset 0xa0 in strlib.so and we want to print +both parameters when the uprobe is hit (on x86_64): + +$ echo 'p:func /lib/strlib.so:0xa0 +0(%di):string +0(%si):string' > \ + /sys/kernel/debug/tracing/uprobe_events + +When the function is called as func("foo", "bar") and we hit the probe, +the trace file shows a line like the following: + + [...] func: (0x7f7e683706a0) arg1="foobar" arg2="bar" + +Note the extra "bar" printed as part of arg1. This behaviour stacks up +for additional string arguments. + +The strings are stored in a dynamically growing part of the uprobe +buffer by fetch_store_string() after copying them from userspace via +strncpy_from_user(). The return value of strncpy_from_user() is then +directly used as the required size for the string. However, this does +not take the terminating null byte into account as the documentation +for strncpy_from_user() cleary states that it "[...] returns the +length of the string (not including the trailing NUL)" even though the +null byte will be copied to the destination. + +Therefore, subsequent calls to fetch_store_string() will overwrite +the terminating null byte of the most recently fetched string with +the first character of the current string, leading to the +"accumulation" of strings in earlier arguments in the output. + +Fix this by incrementing the return value of strncpy_from_user() by +one if we did not hit the maximum buffer size. + +Link: http://lkml.kernel.org/r/20190116141629.5752-1-andreas.ziegler@fau.de + +Cc: Ingo Molnar +Cc: stable@vger.kernel.org +Fixes: 5baaa59ef09e ("tracing/probes: Implement 'memory' fetch method for uprobes") +Acked-by: Masami Hiramatsu +Signed-off-by: Andreas Ziegler +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Masami Hiramatsu +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace_uprobe.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/kernel/trace/trace_uprobe.c ++++ b/kernel/trace/trace_uprobe.c +@@ -150,7 +150,14 @@ static void FETCH_FUNC_NAME(memory, stri + + ret = strncpy_from_user(dst, src, maxlen); + if (ret == maxlen) +- dst[--ret] = '\0'; ++ dst[ret - 1] = '\0'; ++ else if (ret >= 0) ++ /* ++ * Include the terminating null byte. In this case it ++ * was copied by strncpy_from_user but not accounted ++ * for in ret. ++ */ ++ ret++; + + if (ret < 0) { /* Failed to fetch string */ + ((u8 *)get_rloc_data(dest))[0] = '\0'; diff --git a/queue-3.18/x86-a.out-clear-the-dump-structure-initially.patch b/queue-3.18/x86-a.out-clear-the-dump-structure-initially.patch new file mode 100644 index 00000000000..97b6ee2b1cb --- /dev/null +++ b/queue-3.18/x86-a.out-clear-the-dump-structure-initially.patch @@ -0,0 +1,59 @@ +From 10970e1b4be9c74fce8ab6e3c34a7d718f063f2c Mon Sep 17 00:00:00 2001 +From: Borislav Petkov +Date: Tue, 12 Feb 2019 14:28:03 +0100 +Subject: x86/a.out: Clear the dump structure initially + +From: Borislav Petkov + +commit 10970e1b4be9c74fce8ab6e3c34a7d718f063f2c upstream. + +dump_thread32() in aout_core_dump() does not clear the user32 structure +allocated on the stack as the first thing on function entry. + +As a result, the dump.u_comm, dump.u_ar0 and dump.signal which get +assigned before the clearing, get overwritten. + +Rename that function to fill_dump() to make it clear what it does and +call it first thing. + +This was caught while staring at a patch by Derek Robson +. + +Signed-off-by: Borislav Petkov +Cc: Derek Robson +Cc: Linus Torvalds +Cc: Michael Matz +Cc: x86@kernel.org +Cc: +Link: https://lkml.kernel.org/r/20190202005512.3144-1-robsonde@gmail.com +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/ia32/ia32_aout.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/x86/ia32/ia32_aout.c ++++ b/arch/x86/ia32/ia32_aout.c +@@ -50,7 +50,7 @@ static unsigned long get_dr(int n) + /* + * fill in the user structure for a core dump.. + */ +-static void dump_thread32(struct pt_regs *regs, struct user32 *dump) ++static void fill_dump(struct pt_regs *regs, struct user32 *dump) + { + u32 fs, gs; + memset(dump, 0, sizeof(*dump)); +@@ -156,10 +156,12 @@ static int aout_core_dump(struct coredum + fs = get_fs(); + set_fs(KERNEL_DS); + has_dumped = 1; ++ ++ fill_dump(cprm->regs, &dump); ++ + strncpy(dump.u_comm, current->comm, sizeof(current->comm)); + dump.u_ar0 = offsetof(struct user32, regs); + dump.signal = cprm->siginfo->si_signo; +- dump_thread32(cprm->regs, &dump); + + /* + * If the size of the dump file exceeds the rlimit, then see