Skip to content

Commit e72b0ab

Browse files
liutgnulian-bo
authored andcommitted
x86_64: Fix 'bt -S/-I' segfault issue
The "pcp" and "spp" can be NULL for "bt -S/-I", but the value is not checked before pointer dereference, which lead to segfault error. This patch fix this by delay the pointer dereference after x86_64_get_dumpfile_stack_frame(). Before: crash> bt -S ffffbccee0087ab8 PID: 2179 TASK: ffffa0f78912a3c0 CPU: 43 COMMAND: "bash" Segmentation fault (core dumped) After: crash> bt -S ffffbccee0087ab8 PID: 2179 TASK: ffffa0f78912a3c0 CPU: 43 COMMAND: "bash" #0 [ffffbccee0087b10] __crash_kexec at ffffffffad20c30a #1 [ffffbccee0087bd0] panic at ffffffffadcbce30 #2 [ffffbccee0087c50] sysrq_handle_crash at ffffffffad802b86 ... Reported-by: Kazuhito Hagio <[email protected]> Signed-off-by: Tao Liu <[email protected]>
1 parent 0f39e33 commit e72b0ab

File tree

1 file changed

+18
-18
lines changed

1 file changed

+18
-18
lines changed

x86_64.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5009,16 +5009,11 @@ static void
50095009
x86_64_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
50105010
{
50115011
struct user_regs_bitmap_struct *ur_bitmap;
5012-
ulong pcp_save = *pcp;
5013-
ulong spp_save = *spp;
5014-
ulong sp;
5012+
ulong sp = 0;
50155013

50165014
if (bt->flags & BT_SKIP_IDLE)
50175015
bt->flags &= ~BT_SKIP_IDLE;
5018-
if (pcp)
5019-
*pcp = x86_64_get_pc(bt);
5020-
if (spp)
5021-
sp = *spp = x86_64_get_sp(bt);
5016+
50225017
ur_bitmap = (struct user_regs_bitmap_struct *)GETBUF(sizeof(*ur_bitmap));
50235018
memset(ur_bitmap, 0, sizeof(*ur_bitmap));
50245019

@@ -5091,31 +5086,36 @@ x86_64_get_stack_frame(struct bt_info *bt, ulong *pcp, ulong *spp)
50915086
if (bt->flags & BT_DUMPFILE_SEARCH) {
50925087
FREEBUF(ur_bitmap);
50935088
bt->need_free = FALSE;
5094-
*pcp = pcp_save;
5095-
*spp = spp_save;
50965089
return x86_64_get_dumpfile_stack_frame(bt, pcp, spp);
50975090
}
50985091
}
50995092
} else {
51005093
if (!is_task_active(bt->task)) {
5101-
readmem(*spp, KVADDR, &(ur_bitmap->ur.bp),
5102-
sizeof(ulong), "ur_bitmap->ur.bp", FAULT_ON_ERROR);
5103-
SET_REG_BITMAP(ur_bitmap->bitmap, x86_64_user_regs_struct, bp);
5094+
if (spp) {
5095+
*spp = x86_64_get_sp(bt);
5096+
readmem(*spp, KVADDR, &(ur_bitmap->ur.bp),
5097+
sizeof(ulong), "ur_bitmap->ur.bp", FAULT_ON_ERROR);
5098+
SET_REG_BITMAP(ur_bitmap->bitmap, x86_64_user_regs_struct, bp);
5099+
}
51045100
} else {
51055101
if (bt->flags & BT_DUMPFILE_SEARCH) {
51065102
FREEBUF(ur_bitmap);
51075103
bt->need_free = FALSE;
5108-
*pcp = pcp_save;
5109-
*spp = spp_save;
51105104
return x86_64_get_dumpfile_stack_frame(bt, pcp, spp);
51115105
}
51125106
}
51135107
}
51145108

5115-
ur_bitmap->ur.ip = *pcp;
5116-
ur_bitmap->ur.sp = sp;
5117-
SET_REG_BITMAP(ur_bitmap->bitmap, x86_64_user_regs_struct, ip);
5118-
SET_REG_BITMAP(ur_bitmap->bitmap, x86_64_user_regs_struct, sp);
5109+
if (pcp) {
5110+
*pcp = x86_64_get_pc(bt);
5111+
ur_bitmap->ur.ip = *pcp;
5112+
SET_REG_BITMAP(ur_bitmap->bitmap, x86_64_user_regs_struct, ip);
5113+
}
5114+
if (spp) {
5115+
*spp = x86_64_get_sp(bt);
5116+
ur_bitmap->ur.sp = sp + *spp;
5117+
SET_REG_BITMAP(ur_bitmap->bitmap, x86_64_user_regs_struct, sp);
5118+
}
51195119

51205120
bt->machdep = ur_bitmap;
51215121
bt->need_free = TRUE;

0 commit comments

Comments
 (0)