diff --git a/0001-Output-prompt-when-stdin-is-not-a-TTY.patch b/0001-Output-prompt-when-stdin-is-not-a-TTY.patch new file mode 100644 index 0000000..d26ef54 --- /dev/null +++ b/0001-Output-prompt-when-stdin-is-not-a-TTY.patch @@ -0,0 +1,71 @@ +From 8527bbff71cbdfd90a67d5cec4a1d94156e6bf13 Mon Sep 17 00:00:00 2001 +From: Hsin-Yi Wang +Date: Wed, 31 May 2023 14:01:36 +0800 +Subject: [PATCH 1/5] Output prompt when stdin is not a TTY + +When stdin is not a TTY, prompt ("crash> ") won't be displayed. If +another process interact with crash with piped stdin/stdout, it will not +get the prompt as a delimiter. + +Compared to other debugger like gdb, crash seems intended to give a +prompt in this case in the beginning of process_command_line(). It +checks if pc->flags does NOT have any of +READLINE|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE, a +prompt should be printed. The check will never be true since READLINE is +set in setup_environment() unconditionally. + +It makes more sense to change the READLINE flag in the check to TTY +instead. Besides this change, the prompt in process_command_line() should +only be print when it's not in the middle of processing the input file +recovering from a previous FATAL command, because the prompt will be +displayed by the exec_input_file(). + +Additionally, when stdin is not TTY, repeat the command line from user +after prompt, which can give more context. + +The prompt and command line can be opt out by using the silent (-s) flag. + +Signed-off-by: Hsin-Yi Wang +Signed-off-by: Lianbo Jiang +--- + cmdline.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/cmdline.c b/cmdline.c +index ded6551c2597..b7f919ae2279 100644 +--- a/cmdline.c ++++ b/cmdline.c +@@ -64,8 +64,8 @@ process_command_line(void) + fp = stdout; + BZERO(pc->command_line, BUFSIZE); + +- if (!(pc->flags & +- (READLINE|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE))) ++ if (!pc->ifile_in_progress && !(pc->flags & ++ (TTY|SILENT|CMDLINE_IFILE|RCHOME_IFILE|RCLOCAL_IFILE))) + fprintf(fp, "%s", pc->prompt); + fflush(fp); + +@@ -136,12 +136,16 @@ process_command_line(void) + add_history(pc->command_line); + + check_special_handling(pc->command_line); +- } else { +- if (fgets(pc->command_line, BUFSIZE-1, stdin) == NULL) ++ } else { ++ if (fgets(pc->command_line, BUFSIZE-1, stdin) == NULL) + clean_exit(1); ++ if (!(pc->flags & SILENT)) { ++ fprintf(fp, "%s", pc->command_line); ++ fflush(fp); ++ } + clean_line(pc->command_line); + strcpy(pc->orig_line, pc->command_line); +- } ++ } + + /* + * First clean out all linefeeds and leading/trailing spaces. +-- +2.37.1 + diff --git a/0002-x86_64-Fix-bt-command-printing-stale-entries-on-Linu.patch b/0002-x86_64-Fix-bt-command-printing-stale-entries-on-Linu.patch new file mode 100644 index 0000000..5c4b862 --- /dev/null +++ b/0002-x86_64-Fix-bt-command-printing-stale-entries-on-Linu.patch @@ -0,0 +1,345 @@ +From 77d8621876c1c6a3a25b91e464ba588a542485fb Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Thu, 18 May 2023 16:53:54 +0900 +Subject: [PATCH 2/5] x86_64: Fix "bt" command printing stale entries on Linux + 6.4 and later + +Kernel commit fb799447ae29 ("x86,objtool: Split UNWIND_HINT_EMPTY in +two"), which is contained in Linux 6.4 and later kernels, changed +ORC_TYPE_CALL macro from 0 to 2. As a result, the "bt" command cannot +use ORC entries, and can display stale entries in a call trace. + + crash> bt 1 + PID: 1 TASK: ffff93cd06294180 CPU: 51 COMMAND: "systemd" + #0 [ffffb72bc00cbc98] __schedule at ffffffff86e52aae + #1 [ffffb72bc00cbd00] schedule at ffffffff86e52f6a + #2 [ffffb72bc00cbd18] schedule_hrtimeout_range_clock at ffffffff86e58ef5 + #3 [ffffb72bc00cbd88] ep_poll at ffffffff8669624d + #4 [ffffb72bc00cbe28] do_epoll_wait at ffffffff86696371 + #5 [ffffb72bc00cbe30] do_timerfd_settime at ffffffff8669902b << + #6 [ffffb72bc00cbe60] __x64_sys_epoll_wait at ffffffff86696bf0 + #7 [ffffb72bc00cbeb0] do_syscall_64 at ffffffff86e3feb9 + #8 [ffffb72bc00cbee0] __task_pid_nr_ns at ffffffff863330d7 << + #9 [ffffb72bc00cbf08] syscall_exit_to_user_mode at ffffffff86e466b2 << stale entries + #10 [ffffb72bc00cbf18] do_syscall_64 at ffffffff86e3fec9 << + #11 [ffffb72bc00cbf50] entry_SYSCALL_64_after_hwframe at ffffffff870000aa + +Also, kernel commit ffb1b4a41016 added a member to struct orc_entry. +Although this does not affect the crash's unwinder, its debugging +information can be displayed incorrectly. + +To fix these, +(1) introduce "kernel_orc_entry_6_4" structure corresponding to 6.4 and + abstruction layer "orc_entry" structure in crash, +(2) switch ORC_TYPE_CALL to 2 or 0 with kernel's orc_entry structure. + +Related orc_entry history: + v4.14 39358a033b2e introduced struct orc_entry + v4.19 d31a580266ee added orc_entry.end member + v6.3 ffb1b4a41016 added orc_entry.signal member + v6.4 fb799447ae29 removed end member and changed type member to 3 bits + +Signed-off-by: Kazuhito Hagio +Signed-off-by: Lianbo Jiang +--- + defs.h | 28 ++++++++++++- + x86_64.c | 119 +++++++++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 119 insertions(+), 28 deletions(-) + +diff --git a/defs.h b/defs.h +index 11fdc17e60d0..bfda0c48d37b 100644 +--- a/defs.h ++++ b/defs.h +@@ -6363,9 +6363,29 @@ typedef struct __attribute__((__packed__)) { + unsigned int sp_reg:4; + unsigned int bp_reg:4; + unsigned int type:2; ++ unsigned int signal:1; + unsigned int end:1; + } kernel_orc_entry; + ++typedef struct __attribute__((__packed__)) { ++ signed short sp_offset; ++ signed short bp_offset; ++ unsigned int sp_reg:4; ++ unsigned int bp_reg:4; ++ unsigned int type:3; ++ unsigned int signal:1; ++} kernel_orc_entry_6_4; ++ ++typedef struct orc_entry { ++ signed short sp_offset; ++ signed short bp_offset; ++ unsigned int sp_reg; ++ unsigned int bp_reg; ++ unsigned int type; ++ unsigned int signal; ++ unsigned int end; ++} orc_entry; ++ + struct ORC_data { + int module_ORC; + uint lookup_num_blocks; +@@ -6376,10 +6396,13 @@ struct ORC_data { + ulong orc_lookup; + ulong ip_entry; + ulong orc_entry; +- kernel_orc_entry kernel_orc_entry; ++ orc_entry orc_entry_data; ++ int has_signal; ++ int has_end; + }; + +-#define ORC_TYPE_CALL 0 ++#define ORC_TYPE_CALL ((machdep->flags & ORC_6_4) ? 2 : 0) ++/* The below entries are not used and must be updated if we use them. */ + #define ORC_TYPE_REGS 1 + #define ORC_TYPE_REGS_IRET 2 + #define UNWIND_HINT_TYPE_SAVE 3 +@@ -6456,6 +6479,7 @@ struct machine_specific { + #define ORC (0x4000) + #define KPTI (0x8000) + #define L1TF (0x10000) ++#define ORC_6_4 (0x20000) + + #define VM_FLAGS (VM_ORIG|VM_2_6_11|VM_XEN|VM_XEN_RHEL4|VM_5LEVEL) + +diff --git a/x86_64.c b/x86_64.c +index 693a08bea758..87e87ae6e1e8 100644 +--- a/x86_64.c ++++ b/x86_64.c +@@ -132,9 +132,9 @@ static void GART_init(void); + static void x86_64_exception_stacks_init(void); + static int in_START_KERNEL_map(ulong); + static ulong orc_ip(ulong); +-static kernel_orc_entry *__orc_find(ulong, ulong, uint, ulong); +-static kernel_orc_entry *orc_find(ulong); +-static kernel_orc_entry *orc_module_find(ulong); ++static orc_entry *__orc_find(ulong, ulong, uint, ulong); ++static orc_entry *orc_find(ulong); ++static orc_entry *orc_module_find(ulong); + static ulong ip_table_to_vaddr(ulong); + static void orc_dump(ulong); + +@@ -806,6 +806,8 @@ x86_64_dump_machdep_table(ulong arg) + fprintf(fp, "%sFRAMESIZE_DEBUG", others++ ? "|" : ""); + if (machdep->flags & ORC) + fprintf(fp, "%sORC", others++ ? "|" : ""); ++ if (machdep->flags & ORC_6_4) ++ fprintf(fp, "%sORC_6_4", others++ ? "|" : ""); + if (machdep->flags & FRAMEPOINTER) + fprintf(fp, "%sFRAMEPOINTER", others++ ? "|" : ""); + if (machdep->flags & GART_REGION) +@@ -980,6 +982,8 @@ x86_64_dump_machdep_table(ulong arg) + fprintf(fp, " ORC_data: %s", machdep->flags & ORC ? "\n" : "(unused)\n"); + if (machdep->flags & ORC) { + fprintf(fp, " module_ORC: %s\n", ms->orc.module_ORC ? "TRUE" : "FALSE"); ++ fprintf(fp, " has_signal: %s\n", ms->orc.has_signal ? "TRUE" : "FALSE"); ++ fprintf(fp, " has_end: %s\n", ms->orc.has_end ? "TRUE" : "FALSE"); + fprintf(fp, " lookup_num_blocks: %d\n", ms->orc.lookup_num_blocks); + fprintf(fp, " __start_orc_unwind_ip: %lx\n", ms->orc.__start_orc_unwind_ip); + fprintf(fp, " __stop_orc_unwind_ip: %lx\n", ms->orc.__stop_orc_unwind_ip); +@@ -988,14 +992,18 @@ x86_64_dump_machdep_table(ulong arg) + fprintf(fp, " orc_lookup: %lx\n", ms->orc.orc_lookup); + fprintf(fp, " ip_entry: %lx\n", ms->orc.ip_entry); + fprintf(fp, " orc_entry: %lx\n", ms->orc.orc_entry); +- fprintf(fp, " kernel_orc_entry:\n"); +- fprintf(fp, " sp_offset: %d\n", ms->orc.kernel_orc_entry.sp_offset); +- fprintf(fp, " bp_offset: %d\n", ms->orc.kernel_orc_entry.bp_offset); +- fprintf(fp, " sp_reg: %d\n", ms->orc.kernel_orc_entry.sp_reg); +- fprintf(fp, " bp_reg: %d\n", ms->orc.kernel_orc_entry.bp_reg); +- fprintf(fp, " type: %d\n", ms->orc.kernel_orc_entry.type); +- if (MEMBER_EXISTS("orc_entry", "end")) +- fprintf(fp, " end: %d\n", ms->orc.kernel_orc_entry.end); ++ fprintf(fp, " orc_entry_data:\n"); ++ fprintf(fp, " sp_offset: %d\n", ms->orc.orc_entry_data.sp_offset); ++ fprintf(fp, " bp_offset: %d\n", ms->orc.orc_entry_data.bp_offset); ++ fprintf(fp, " sp_reg: %d\n", ms->orc.orc_entry_data.sp_reg); ++ fprintf(fp, " bp_reg: %d\n", ms->orc.orc_entry_data.bp_reg); ++ fprintf(fp, " type: %d\n", ms->orc.orc_entry_data.type); ++ if (ms->orc.has_signal) ++ fprintf(fp, " signal: %d\n", ms->orc.orc_entry_data.signal); ++ else ++ fprintf(fp, " signal: (n/a)\n"); ++ if (ms->orc.has_end) ++ fprintf(fp, " end: %d\n", ms->orc.orc_entry_data.end); + else + fprintf(fp, " end: (n/a)\n"); + } +@@ -6440,6 +6448,12 @@ x86_64_ORC_init(void) + MEMBER_OFFSET_INIT(inactive_task_frame_bp, "inactive_task_frame", "bp"); + MEMBER_OFFSET_INIT(inactive_task_frame_ret_addr, "inactive_task_frame", "ret_addr"); + ++ orc->has_signal = MEMBER_EXISTS("orc_entry", "signal"); /* added at 6.3 */ ++ orc->has_end = MEMBER_EXISTS("orc_entry", "end"); /* removed at 6.4 */ ++ ++ if (orc->has_signal && !orc->has_end) ++ machdep->flags |= ORC_6_4; ++ + machdep->flags |= ORC; + } + +@@ -8522,7 +8536,7 @@ x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp, char *stack_ + int reterror; + int arg_exists; + int exception; +- kernel_orc_entry *korc; ++ orc_entry *korc; + + if (!(bt->flags & BT_FRAMESIZE_DEBUG)) { + if ((bt->flags & BT_FRAMESIZE_IGNORE_MASK) || +@@ -8608,11 +8622,14 @@ x86_64_get_framesize(struct bt_info *bt, ulong textaddr, ulong rsp, char *stack_ + + if ((machdep->flags & ORC) && (korc = orc_find(textaddr))) { + if (CRASHDEBUG(1)) { ++ struct ORC_data *orc = &machdep->machspec->orc; + fprintf(fp, + "rsp: %lx textaddr: %lx -> spo: %d bpo: %d spr: %d bpr: %d type: %d", + rsp, textaddr, korc->sp_offset, korc->bp_offset, + korc->sp_reg, korc->bp_reg, korc->type); +- if (MEMBER_EXISTS("orc_entry", "end")) ++ if (orc->has_signal) ++ fprintf(fp, " signal: %d", korc->signal); ++ if (orc->has_end) + fprintf(fp, " end: %d", korc->end); + fprintf(fp, "\n"); + } +@@ -9118,7 +9135,53 @@ orc_ip(ulong ip) + return (ip + ip_entry); + } + +-static kernel_orc_entry * ++static orc_entry * ++orc_get_entry(struct ORC_data *orc) ++{ ++ struct orc_entry *entry = &orc->orc_entry_data; ++ ++ if (machdep->flags & ORC_6_4) { ++ kernel_orc_entry_6_4 korc; ++ ++ if (!readmem(orc->orc_entry, KVADDR, &korc, sizeof(kernel_orc_entry_6_4), ++ "kernel orc_entry", RETURN_ON_ERROR|QUIET)) ++ return NULL; ++ ++ entry->sp_offset = korc.sp_offset; ++ entry->bp_offset = korc.bp_offset; ++ entry->sp_reg = korc.sp_reg; ++ entry->bp_reg = korc.bp_reg; ++ entry->type = korc.type; ++ entry->signal = korc.signal; ++ } else { ++ kernel_orc_entry korc; ++ ++ if (!readmem(orc->orc_entry, KVADDR, &korc, sizeof(kernel_orc_entry), ++ "kernel orc_entry", RETURN_ON_ERROR|QUIET)) ++ return NULL; ++ ++ entry->sp_offset = korc.sp_offset; ++ entry->bp_offset = korc.bp_offset; ++ entry->sp_reg = korc.sp_reg; ++ entry->bp_reg = korc.bp_reg; ++ entry->type = korc.type; ++ if (orc->has_end) { ++ /* ++ * orc_entry.signal was inserted before orc_entry.end. ++ * see ffb1b4a41016. ++ */ ++ if (orc->has_signal) { ++ entry->signal = korc.signal; ++ entry->end = korc.end; ++ } else ++ entry->end = korc.signal; /* on purpose */ ++ } ++ } ++ ++ return entry; ++} ++ ++static orc_entry * + __orc_find(ulong ip_table_ptr, ulong u_table_ptr, uint num_entries, ulong ip) + { + int index; +@@ -9128,7 +9191,7 @@ __orc_find(ulong ip_table_ptr, ulong u_table_ptr, uint num_entries, ulong ip) + int *ip_table = (int *)ip_table_ptr; + struct ORC_data *orc = &machdep->machspec->orc; + ulong vaddr; +- kernel_orc_entry *korc; ++ orc_entry *korc; + + if (CRASHDEBUG(2)) { + int i, ip_entry; +@@ -9172,18 +9235,20 @@ __orc_find(ulong ip_table_ptr, ulong u_table_ptr, uint num_entries, ulong ip) + + orc->ip_entry = (ulong)found; + orc->orc_entry = u_table_ptr + (index * SIZE(orc_entry)); +- if (!readmem(orc->orc_entry, KVADDR, &orc->kernel_orc_entry, +- sizeof(kernel_orc_entry), "kernel orc_entry", RETURN_ON_ERROR|QUIET)) ++ ++ if (!orc_get_entry(orc)) + return NULL; + +- korc = &orc->kernel_orc_entry; ++ korc = &orc->orc_entry_data; + + if (CRASHDEBUG(2)) { + fprintf(fp, " found: %lx index: %d\n", (ulong)found, index); + fprintf(fp, + " orc_entry: %lx sp_offset: %d bp_offset: %d sp_reg: %d bp_reg: %d type: %d", + orc->orc_entry, korc->sp_offset, korc->bp_offset, korc->sp_reg, korc->bp_reg, korc->type); +- if (MEMBER_EXISTS("orc_entry", "end")) ++ if (orc->has_signal) ++ fprintf(fp, " signal: %d", korc->signal); ++ if (orc->has_end) + fprintf(fp, " end: %d", korc->end); + fprintf(fp, "\n"); + } +@@ -9196,7 +9261,7 @@ __orc_find(ulong ip_table_ptr, ulong u_table_ptr, uint num_entries, ulong ip) + #define LOOKUP_START_IP (unsigned long)kt->stext + #define LOOKUP_STOP_IP (unsigned long)kt->etext + +-static kernel_orc_entry * ++static orc_entry * + orc_find(ulong ip) + { + unsigned int idx, start, stop; +@@ -9266,7 +9331,7 @@ orc_find(ulong ip) + orc->__start_orc_unwind + (start * SIZE(orc_entry)), stop - start, ip); + } + +-static kernel_orc_entry * ++static orc_entry * + orc_module_find(ulong ip) + { + struct load_module *lm; +@@ -9313,7 +9378,7 @@ static void + orc_dump(ulong ip) + { + struct ORC_data *orc = &machdep->machspec->orc; +- kernel_orc_entry *korc; ++ orc_entry *korc; + ulong vaddr, offset; + struct syment *sp, *orig; + +@@ -9336,13 +9401,15 @@ next_in_func: + fprintf(fp, "%s+%ld -> ", sp->name, offset); + else + fprintf(fp, "(unresolved) -> "); +- if (!readmem(orc->orc_entry, KVADDR, &orc->kernel_orc_entry, sizeof(kernel_orc_entry), +- "kernel orc_entry", RETURN_ON_ERROR)) ++ ++ if (!orc_get_entry(orc)) + error(FATAL, "cannot read orc_entry\n"); +- korc = &orc->kernel_orc_entry; ++ korc = &orc->orc_entry_data; + fprintf(fp, "orc: %lx spo: %d bpo: %d spr: %d bpr: %d type: %d", + orc->orc_entry, korc->sp_offset, korc->bp_offset, korc->sp_reg, korc->bp_reg, korc->type); +- if (MEMBER_EXISTS("orc_entry", "end")) ++ if (orc->has_signal) ++ fprintf(fp, " signal: %d", korc->signal); ++ if (orc->has_end) + fprintf(fp, " end: %d", korc->end); + fprintf(fp, "\n"); + +-- +2.37.1 + diff --git a/0003-Fix-invalid-structure-size-error-during-crash-startu.patch b/0003-Fix-invalid-structure-size-error-during-crash-startu.patch new file mode 100644 index 0000000..5d6a9af --- /dev/null +++ b/0003-Fix-invalid-structure-size-error-during-crash-startu.patch @@ -0,0 +1,48 @@ +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/0004-Revert-Fix-segfault-in-arm64_is_kernel_exception_fra.patch b/0004-Revert-Fix-segfault-in-arm64_is_kernel_exception_fra.patch new file mode 100644 index 0000000..12c0f5c --- /dev/null +++ b/0004-Revert-Fix-segfault-in-arm64_is_kernel_exception_fra.patch @@ -0,0 +1,68 @@ +From 91a76958e4a8a9fb67ac61166ff36e8dc961b3b9 Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Wed, 7 Jun 2023 18:37:33 +0900 +Subject: [PATCH 4/5] Revert "Fix segfault in arm64_is_kernel_exception_frame() + when corrupt stack pointer address is given" + +This reverts commit 9868ebc8e648e5791764a51567a23efae7170d9b. + +The commit 9868ebc8e648e5791764a51567a23efae7170d9b causes the issue +that bt command fails to show backtraces for the tasks that is running +in the user mode at the moment of the kernel panic as follows: + + crash> bt 1734 + PID: 1734 TASK: ffff000000392200 CPU: 4 COMMAND: "insmod" + bt: invalid stack pointer is given + +The root cause is that while the commit added a sanity check into +STACK_OFFSET_TYPE() to validate if a given candidate address of any +interrupt or exception frame is contained within the range of the +corresponding kernel stack, the premise that the STACK_OFFSET_TYPE() +should not return out-of-the-buffer address, is wrong. + +Reexamining the relevant surrounding part of the backtracing code, it +looks to me now that the STACK_OFFSET_TYPE() is originally expected to +return an out-of-the-buffer address, like the address of the top of +the corresponding kernel stack, e.g. at here: + + static int + arm64_in_kdump_text(struct bt_info *bt, struct arm64_stackframe *frame) + { + ... + if (bt->flags & BT_USER_SPACE) + start = (ulong *)&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(bt->stacktop))]; + else { + +Note that the above bt 1734 aborts here. + +Hence, the current implementation policy around STACK_OFFSET_TYPE() +looks that the caller side is responsible for understanding the fact +in advance and for avoiding making buffer overrun carefully. + +To fix this issue, revert the commit. + +Signed-off-by: HATAYAMA Daisuke +Signed-off-by: Lianbo Jiang +--- + defs.h | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/defs.h b/defs.h +index bfda0c48d37b..3e7d6cfbc6a8 100644 +--- a/defs.h ++++ b/defs.h +@@ -976,10 +976,7 @@ struct bt_info { + + #define STACK_OFFSET_TYPE(OFF) \ + (((ulong)(OFF) > STACKSIZE()) ? \ +- (((ulong)(OFF) < (ulong)(bt->stackbase) || (ulong)(OFF) >= (ulong)(bt->stackbase) + STACKSIZE()) ? \ +- error(FATAL, "invalid stack pointer is given\n") : \ +- (ulong)((ulong)(OFF) - (ulong)(bt->stackbase))) : \ +- (ulong)(OFF)) ++ (ulong)((ulong)(OFF) - (ulong)(bt->stackbase)) : (ulong)(OFF)) + + #define GET_STACK_ULONG(OFF) \ + *((ulong *)((char *)(&bt->stackbuf[(ulong)(STACK_OFFSET_TYPE(OFF))]))) +-- +2.37.1 + diff --git a/0005-arm64-Fix-again-segfault-in-arm64_is_kernel_exceptio.patch b/0005-arm64-Fix-again-segfault-in-arm64_is_kernel_exceptio.patch new file mode 100644 index 0000000..1526ec3 --- /dev/null +++ b/0005-arm64-Fix-again-segfault-in-arm64_is_kernel_exceptio.patch @@ -0,0 +1,45 @@ +From 6c8cd9b5dcf48221e5f75fc5850bb4719d77acce Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Wed, 7 Jun 2023 18:37:34 +0900 +Subject: [PATCH 5/5] 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 +Signed-off-by: Lianbo Jiang +--- + arm64.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arm64.c b/arm64.c +index efbdccbec9d3..67b1a2244810 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) && +-- +2.37.1 + diff --git a/crash.spec b/crash.spec index c8dd386..a22f1e3 100644 --- a/crash.spec +++ b/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: 7%{?dist} +Release: 8%{?dist} License: GPLv3 Group: Development/Debuggers Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz @@ -111,9 +111,14 @@ Patch91: 0003-Fix-kmem-v-option-displaying-no-regions-on-Linux-6.3.patch Patch92: 0004-arm64-x86_64-Enhance-vtop-command-to-show-zero_pfn-i.patch Patch93: 0005-diskdump-netdump-fix-segmentation-fault-caused-by-fa.patch Patch94: 0006-Fix-segfault-in-arm64_is_kernel_exception_frame-when.patch -Patch95: lzo_snappy_zstd.patch -Patch96: rhel8_build.patch -Patch97: rhel8-freepointer.patch +Patch95: 0001-Output-prompt-when-stdin-is-not-a-TTY.patch +Patch96: 0002-x86_64-Fix-bt-command-printing-stale-entries-on-Linu.patch +Patch97: 0003-Fix-invalid-structure-size-error-during-crash-startu.patch +Patch98: 0004-Revert-Fix-segfault-in-arm64_is_kernel_exception_fra.patch +Patch99: 0005-arm64-Fix-again-segfault-in-arm64_is_kernel_exceptio.patch +Patch100: lzo_snappy_zstd.patch +Patch101: rhel8_build.patch +Patch102: rhel8-freepointer.patch %description The core analysis suite is a self-contained tool that can be used to @@ -232,6 +237,11 @@ offered by Mission Critical Linux, or the LKCD kernel patch. %patch95 -p1 %patch96 -p1 %patch97 -p1 +%patch98 -p1 +%patch99 -p1 +%patch100 -p1 +%patch101 -p1 +%patch102 -p1 %build cp %{SOURCE1} . @@ -262,6 +272,10 @@ rm -rf %{buildroot} %{_includedir}/* %changelog +* Thu Jun 15 2023 Lianbo Jiang - 7.3.2-8 +- arm64: Fix again segfault in arm64_is_kernel_exception_frame() +- Fix invalid structure size error during crash startup on ppc64 + * Wed Jun 07 2023 Lianbo Jiang - 7.3.2-7 - Fix segfault caused by failure of stopping CPUs