diff --git a/SOURCES/0029-Fix-invalid-structure-size-error-during-crash-startu.patch b/SOURCES/0029-Fix-invalid-structure-size-error-during-crash-startu.patch new file mode 100644 index 0000000..073a056 --- /dev/null +++ b/SOURCES/0029-Fix-invalid-structure-size-error-during-crash-startu.patch @@ -0,0 +1,47 @@ +From ec1e61b33a705b8be8d116a541c7b076b0429deb Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Mon, 12 Jun 2023 18:50:05 +0800 +Subject: [PATCH 3/5] Fix invalid structure size error during crash startup on + ppc64 + +The crash utility will fail to start session on ppc64 with the following +error: + + # crash vmlinux vmcore -s + + crash: invalid structure size: note_buf + FILE: diskdump.c LINE: 121 FUNCTION: have_crash_notes() + + [./crash] error trace: 101859ac => 10291798 => 10291450 => 10266038 + + 10266038: SIZE_verify+156 + 10291450: have_crash_notes+308 + 10291798: map_cpus_to_prstatus_kdump_cmprs+448 + 101859ac: task_init+11980 + +The reason is that the size of note_buf is not initialized before using +SIZE(note_buf) in the have_crash_notes() on some architectures including +ppc64. Let's initialize it in task_init() to fix this issue. + +Fixes: db8c030857b4 ("diskdump/netdump: fix segmentation fault caused by failure of stopping CPUs") +Signed-off-by: Lianbo Jiang +--- + task.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/task.c b/task.c +index 88941c7b0e4d..2b7467b4193d 100644 +--- a/task.c ++++ b/task.c +@@ -675,6 +675,9 @@ task_init(void) + tt->this_task = pid_to_task(active_pid); + } + else { ++ if (INVALID_SIZE(note_buf)) ++ STRUCT_SIZE_INIT(note_buf, "note_buf_t"); ++ + if (KDUMP_DUMPFILE()) + map_cpus_to_prstatus(); + else if (ELF_NOTES_VALID() && DISKDUMP_DUMPFILE()) +-- +2.37.1 diff --git a/SOURCES/0030-arm64-Fix-again-segfault.patch b/SOURCES/0030-arm64-Fix-again-segfault.patch new file mode 100644 index 0000000..83ec3a3 --- /dev/null +++ b/SOURCES/0030-arm64-Fix-again-segfault.patch @@ -0,0 +1,41 @@ +From 6c8cd9b5dcf48221e5f75fc5850bb4719d77acce Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Wed, 7 Jun 2023 18:37:34 +0900 +Subject: [PATCH] arm64: Fix again segfault in + arm64_is_kernel_exception_frame() when corrupt stack pointer address is given + +This is the second trial from the commit +9868ebc8e648e5791764a51567a23efae7170d9b that was reverted at the +previous commit. + +As described in the previous commit, result of STACK_OFFSET_TYPE() can +be an address out of bt->stackbuf and hence the address needs to be +checked prior to being referred to as an pt_regs object. + +So, to fix the issue, let's check if stkptr points to within the range +of the kernel stack first. + +[ kh: added a warning at Lianbo's suggestion ] + +Signed-off-by: HATAYAMA Daisuke +--- + arm64.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arm64.c b/arm64.c +index efbdccbe..67b1a224 100644 +--- a/arm64.c ++++ b/arm64.c +@@ -2381,6 +2381,12 @@ arm64_is_kernel_exception_frame(struct bt_info *bt, ulong stkptr) + struct arm64_pt_regs *regs; + struct machine_specific *ms = machdep->machspec; + ++ if (stkptr > STACKSIZE() && !INSTACK(stkptr, bt)) { ++ if (CRASHDEBUG(1)) ++ error(WARNING, "stkptr: %lx is outside the kernel stack range\n", stkptr); ++ return FALSE; ++ } ++ + regs = (struct arm64_pt_regs *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(stkptr))]; + + if (INSTACK(regs->sp, bt) && INSTACK(regs->regs[29], bt) && diff --git a/SOURCES/0031-diskdump-netdump-fix-segmentation-fault.patch b/SOURCES/0031-diskdump-netdump-fix-segmentation-fault.patch new file mode 100644 index 0000000..4cc9004 --- /dev/null +++ b/SOURCES/0031-diskdump-netdump-fix-segmentation-fault.patch @@ -0,0 +1,161 @@ +From db8c030857b4e318728c51c20da687906c109d0d Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Tue, 30 May 2023 19:38:34 +0900 +Subject: [PATCH] diskdump/netdump: fix segmentation fault caused by failure of + stopping CPUs + +There's no NMI on ARM. Hence, stopping the non-panicking CPUs from the +panicking CPU via IPI can fail easily if interrupts are being masked +in those moment. Moreover, crash_notes are not initialized for such +unstopped CPUs and the corresponding NT_PRSTATUS notes are not +attached to vmcore. However, crash utility never takes it +consideration such uninitialized crash_notes and then ends with +mapping different NT_PRSTATUS to actually unstopped CPUs. This corrupt +mapping can result crash utility into segmentation fault in the +operations where register values in NT_PRSTATUS notes are used. + +For example: + + crash> bt 1408 + PID: 1408 TASK: ffff000003e22200 CPU: 2 COMMAND: "repro" + Segmentation fault (core dumped) + + crash> help -D + diskdump_data: + filename: 127.0.0.1-2023-05-26-02:21:27/vmcore-ld1 + flags: 46 (KDUMP_CMPRS_LOCAL|ERROR_EXCLUDED|LZO_SUPPORTED) + ...snip... + notes_buf: 1815df0 + num_vmcoredd_notes: 0 + num_prstatus_notes: 5 + notes[0]: 1815df0 (NT_PRSTATUS) + si.signo: 0 si.code: 0 si.errno: 0 + ...snip... + PSTATE: 80400005 FPVALID: 00000000 + notes[4]: 1808f10 (NT_PRSTATUS) + Segmentation fault (core dumped) + +To fix this issue, let's map NT_PRSTATUS to some CPU only if the +corresponding crash_notes is checked to be initialized. + +[ kh: moved existence check for crash_notes out of the loop ] + +Signed-off-by: HATAYAMA Daisuke +Signed-off-by: Kazuhito Hagio +--- + defs.h | 1 + + diskdump.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- + netdump.c | 7 ++++++- + 3 files changed, 51 insertions(+), 2 deletions(-) + +diff --git a/defs.h b/defs.h +index 7d8bb8ab..6520d2f1 100644 +--- a/defs.h ++++ b/defs.h +@@ -7118,6 +7118,7 @@ int dumpfile_is_split(void); + void show_split_dumpfiles(void); + void x86_process_elf_notes(void *, unsigned long); + void *diskdump_get_prstatus_percpu(int); ++int have_crash_notes(int cpu); + void map_cpus_to_prstatus_kdump_cmprs(void); + void diskdump_display_regs(int, FILE *); + void process_elf32_notes(void *, ulong); +diff --git a/diskdump.c b/diskdump.c +index 94bca4de..2c284ff3 100644 +--- a/diskdump.c ++++ b/diskdump.c +@@ -101,12 +101,54 @@ int dumpfile_is_split(void) + return KDUMP_SPLIT(); + } + ++int have_crash_notes(int cpu) ++{ ++ ulong crash_notes, notes_ptr; ++ char *buf, *p; ++ Elf64_Nhdr *note = NULL; ++ ++ if (!readmem(symbol_value("crash_notes"), KVADDR, &crash_notes, ++ sizeof(crash_notes), "crash_notes", RETURN_ON_ERROR)) { ++ error(WARNING, "cannot read \"crash_notes\"\n"); ++ return FALSE; ++ } ++ ++ if ((kt->flags & SMP) && (kt->flags & PER_CPU_OFF)) ++ notes_ptr = crash_notes + kt->__per_cpu_offset[cpu]; ++ else ++ notes_ptr = crash_notes; ++ ++ buf = GETBUF(SIZE(note_buf)); ++ ++ if (!readmem(notes_ptr, KVADDR, buf, ++ SIZE(note_buf), "note_buf_t", RETURN_ON_ERROR)) { ++ error(WARNING, "cpu %d: cannot read NT_PRSTATUS note\n", cpu); ++ return FALSE; ++ } ++ ++ note = (Elf64_Nhdr *)buf; ++ p = buf + sizeof(Elf64_Nhdr); ++ ++ if (note->n_type != NT_PRSTATUS) { ++ error(WARNING, "cpu %d: invalid NT_PRSTATUS note (n_type != NT_PRSTATUS)\n", cpu); ++ return FALSE; ++ } ++ ++ if (!STRNEQ(p, "CORE")) { ++ error(WARNING, "cpu %d: invalid NT_PRSTATUS note (name != \"CORE\")\n", cpu); ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++ + void + map_cpus_to_prstatus_kdump_cmprs(void) + { + void **nt_ptr; + int online, i, j, nrcpus; + size_t size; ++ int crash_notes_exists; + + if (pc->flags2 & QEMU_MEM_DUMP_COMPRESSED) /* notes exist for all cpus */ + goto resize_note_pointers; +@@ -129,9 +171,10 @@ map_cpus_to_prstatus_kdump_cmprs(void) + * Re-populate the array with the notes mapping to online cpus + */ + nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS); ++ crash_notes_exists = kernel_symbol_exists("crash_notes"); + + for (i = 0, j = 0; i < nrcpus; i++) { +- if (in_cpu_map(ONLINE_MAP, i)) { ++ if (in_cpu_map(ONLINE_MAP, i) && (!crash_notes_exists || have_crash_notes(i))) { + dd->nt_prstatus_percpu[i] = nt_ptr[j++]; + dd->num_prstatus_notes = + MAX(dd->num_prstatus_notes, i+1); +diff --git a/netdump.c b/netdump.c +index 4eba66ce..61ddeaa0 100644 +--- a/netdump.c ++++ b/netdump.c +@@ -75,6 +75,7 @@ map_cpus_to_prstatus(void) + void **nt_ptr; + int online, i, j, nrcpus; + size_t size; ++ int crash_notes_exists; + + if (pc->flags2 & QEMU_MEM_DUMP_ELF) /* notes exist for all cpus */ + return; +@@ -97,10 +98,14 @@ map_cpus_to_prstatus(void) + * Re-populate the array with the notes mapping to online cpus + */ + nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS); ++ crash_notes_exists = kernel_symbol_exists("crash_notes"); + + for (i = 0, j = 0; i < nrcpus; i++) { +- if (in_cpu_map(ONLINE_MAP, i)) ++ if (in_cpu_map(ONLINE_MAP, i) && (!crash_notes_exists || have_crash_notes(i))) { + nd->nt_prstatus_percpu[i] = nt_ptr[j++]; ++ nd->num_prstatus_notes = ++ MAX(nd->num_prstatus_notes, i+1); ++ } + } + + FREEBUF(nt_ptr); diff --git a/SPECS/crash.spec b/SPECS/crash.spec index cca4cb6..bd14cc2 100644 --- a/SPECS/crash.spec +++ b/SPECS/crash.spec @@ -4,7 +4,7 @@ Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles Name: crash Version: 7.3.2 -Release: 4%{?dist}.alma +Release: 4%{?dist}.1.alma License: GPLv3 Group: Development/Debuggers Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz @@ -64,6 +64,14 @@ Patch44: 0026-ppc64-still-allow-to-move-on-if-the-emergency-stacks.patch Patch45: 0027-Fix-segmentation-fault-in-page_flags_init_from_pagef.patch Patch46: 0028-Fix-for-ps-vm-commands-to-display-correct-MEM-and-RS.patch +# Patches were taken from: +# https://gitlab.com/redhat/centos-stream/rpms/crash/-/blob/d5edf45d2deeb8a47b29d23b95b286c6b1a16ee4/0003-Fix-invalid-structure-size-error-during-crash-startu.patch +Patch47: 0029-Fix-invalid-structure-size-error-during-crash-startu.patch +# https://github.com/crash-utility/crash/commit/6c8cd9b5dcf48221e5f75fc5850bb4719d77acce.patch +Patch48: 0030-arm64-Fix-again-segfault.patch +# https://github.com/crash-utility/crash/commit/db8c030857b4e318728c51c20da687906c109d0d.patch +Patch49: 0031-diskdump-netdump-fix-segmentation-fault.patch + %description The core analysis suite is a self-contained tool that can be used to investigate either live systems, kernel core dumps created from the @@ -130,6 +138,9 @@ offered by Mission Critical Linux, or the LKCD kernel patch. %patch44 -p1 %patch45 -p1 %patch46 -p1 +%patch47 -p1 +%patch48 -p1 +%patch49 -p1 %build cp %{SOURCE1} . @@ -160,6 +171,11 @@ rm -rf %{buildroot} %{_includedir}/* %changelog +* Wed Aug 09 2023 Edaurd Abdullin - 7.3.2-4.1.alma +- 0029-Fix-invalid-structure-size-error-during-crash-startu.patch +- 0030-arm64-Fix-again-segfault.patch +- 0031-diskdump-netdump-fix-segmentation-fault.patch + * Tue May 16 2023 Andrew Lukoshko - 7.3.2-4.alma - Debrand for AlmaLinux