Release: crash-7.3.2-8
Fixes: [1] arm64: Fix again segfault in arm64_is_kernel_exception_frame() [2] Fix invalid structure size error during crash startup on ppc64 Resolves: rhbz#2211262 Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
This commit is contained in:
parent
1b9b08cbe5
commit
d5edf45d2d
71
0001-Output-prompt-when-stdin-is-not-a-TTY.patch
Normal file
71
0001-Output-prompt-when-stdin-is-not-a-TTY.patch
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
From 8527bbff71cbdfd90a67d5cec4a1d94156e6bf13 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Hsin-Yi Wang <hsinyi@chromium.org>
|
||||||
|
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 <hsinyi@chromium.org>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
345
0002-x86_64-Fix-bt-command-printing-stale-entries-on-Linu.patch
Normal file
345
0002-x86_64-Fix-bt-command-printing-stale-entries-on-Linu.patch
Normal file
@ -0,0 +1,345 @@
|
|||||||
|
From 77d8621876c1c6a3a25b91e464ba588a542485fb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||||
|
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 <k-hagio-ab@nec.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
From ec1e61b33a705b8be8d116a541c7b076b0429deb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
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 <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,68 @@
|
|||||||
|
From 91a76958e4a8a9fb67ac61166ff36e8dc961b3b9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
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 <d.hatayama@fujitsu.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From 6c8cd9b5dcf48221e5f75fc5850bb4719d77acce Mon Sep 17 00:00:00 2001
|
||||||
|
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
||||||
|
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 <d.hatayama@fujitsu.com>
|
||||||
|
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
22
crash.spec
22
crash.spec
@ -4,7 +4,7 @@
|
|||||||
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
|
Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles
|
||||||
Name: crash
|
Name: crash
|
||||||
Version: 7.3.2
|
Version: 7.3.2
|
||||||
Release: 7%{?dist}
|
Release: 8%{?dist}
|
||||||
License: GPLv3
|
License: GPLv3
|
||||||
Group: Development/Debuggers
|
Group: Development/Debuggers
|
||||||
Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz
|
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
|
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
|
Patch93: 0005-diskdump-netdump-fix-segmentation-fault-caused-by-fa.patch
|
||||||
Patch94: 0006-Fix-segfault-in-arm64_is_kernel_exception_frame-when.patch
|
Patch94: 0006-Fix-segfault-in-arm64_is_kernel_exception_frame-when.patch
|
||||||
Patch95: lzo_snappy_zstd.patch
|
Patch95: 0001-Output-prompt-when-stdin-is-not-a-TTY.patch
|
||||||
Patch96: rhel8_build.patch
|
Patch96: 0002-x86_64-Fix-bt-command-printing-stale-entries-on-Linu.patch
|
||||||
Patch97: rhel8-freepointer.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
|
%description
|
||||||
The core analysis suite is a self-contained tool that can be used to
|
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
|
%patch95 -p1
|
||||||
%patch96 -p1
|
%patch96 -p1
|
||||||
%patch97 -p1
|
%patch97 -p1
|
||||||
|
%patch98 -p1
|
||||||
|
%patch99 -p1
|
||||||
|
%patch100 -p1
|
||||||
|
%patch101 -p1
|
||||||
|
%patch102 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
cp %{SOURCE1} .
|
cp %{SOURCE1} .
|
||||||
@ -262,6 +272,10 @@ rm -rf %{buildroot}
|
|||||||
%{_includedir}/*
|
%{_includedir}/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Jun 15 2023 Lianbo Jiang <lijiang@redhat.com> - 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 <lijiang@redhat.com> - 7.3.2-7
|
* Wed Jun 07 2023 Lianbo Jiang <lijiang@redhat.com> - 7.3.2-7
|
||||||
- Fix segfault caused by failure of stopping CPUs
|
- Fix segfault caused by failure of stopping CPUs
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user