[Crash-utility] [PATCH] Fix a potential segfault for the ARM64 "bt -S <stack-address>" command

Dave Anderson anderson at redhat.com
Mon Nov 4 15:28:48 UTC 2019



----- Original Message -----
> Hi Dave,
> I‘m working on arm64 kdump by crash-7.2.7++.
> There is a potential segmentation violation due to an invalid exception frame
> before
> transitioning to the process stack when try using the bt command's "-S
> <stack-address>" options.
> For example, take the sp argument from the log:
> [   84.048650] pc : _raw_spin_lock+0x30/0x88
> [   84.048658] lr : lowmem_scan+0x45c/0xbd0
> [   84.048661] sp : ffffff800c42ba00 pstate : 20c00145
> 
> A segmentation violation is generated as below:
> crash> bt -S ffffff800c42ba00 108
> PID: 108    TASK: ffffffcd74122000  CPU: 5   COMMAND: "rtmm_reclaim"
> bt: WARNING: cannot determine starting stack frame for task ffffffcd74122000
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x000055555572de2b in arm64_is_kernel_exception_frame (bt=0x7fffffffd640,
> stkptr=18446743644915693792) at arm64.c:1785
> warning: Source file is more recent than executable.
> 1785            if (INSTACK(regs->sp, bt) && INSTACK(regs->regs[29], bt) &&
> (gdb) bt
> #0  0x000055555572de2b in arm64_is_kernel_exception_frame (bt=0x7fffffffd640,
> stkptr=18446743644915693792) at arm64.c:1785
> #1  0x000055555572ffaf in arm64_back_trace_cmd (bt=0x7fffffffd640) at
> arm64.c:2594
> #2  0x00005555556ef0c4 in back_trace (bt=0x7fffffffd640) at kernel.c:3164
> #3  0x00005555556ed624 in cmd_bt () at kernel.c:2833
> #4  0x000055555564a73b in exec_command () at main.c:879
> #5  0x000055555564a515 in main_loop () at main.c:826
> #6  0x00005555558b5b43 in captured_command_loop (data=data at entry=0x0) at
> main.c:258
> #7  0x00005555558b46ca in catch_errors (func=func at entry=0x5555558b5b30
> <captured_command_loop>, func_args=func_args at entry=0x0,
>     errstring=errstring at entry=0x555555b0b728 "", mask=mask at entry=6) at
>     exceptions.c:557
> #8  0x00005555558b6c42 in captured_main (data=data at entry=0x7fffffffdfb0) at
> main.c:1064
> #9  0x00005555558b46ca in catch_errors (func=func at entry=0x5555558b5e70
> <captured_main>, func_args=func_args at entry=0x7fffffffdfb0,
>     errstring=errstring at entry=0x555555b0b728 "", mask=mask at entry=6) at
>     exceptions.c:557
> #10 0x00005555558b702e in gdb_main (args=0x7fffffffdfb0) at main.c:1079
> #11 gdb_main_entry (argc=<optimized out>, argv=<optimized out>) at
> main.c:1099
> #12 0x000055555570fc53 in gdb_main_loop (argc=2, argv=0x7fffffffe148) at
> gdb_interface.c:76
> #13 0x000055555564a1e0 in main (argc=4, argv=0x7fffffffe148) at main.c:707
> 
> (gdb) p /x *(struct bt_info *) 0x7fffffffd640
> $4 = {task = 0xffffffcd74122000, flags = 0x0, instptr = 0x0, stkptr =
> 0xffffff800c42ba00, bptr = 0x0, stackbase = 0xffffff800c428000,
>   stacktop = 0xffffff800c42c000, stackbuf = 0x555555f23ae0, tc =
>   0x5555596e1778, hp = 0x7fffffffd5f0, textlist = 0x0, ref = 0x0, frameptr =
>   0x0,
>   call_target = 0x0, machdep = 0x0, debug = 0x0, eframe_ip = 0x0, radix =
>   0x0, cpumask = 0x0}
> 
> The stackframe.fp(0xffffff9c29e4f8e0) is larger than the stacktop address, so
> lead to segmentation violation gernarated by accessing regs->sp:
> (gdb) p /x 18446743644915693792//stkptr
> $5 = 0xffffff9c29e4f8e0
> (gdb) p /x 0xffffff9c29e4f8e0-0xffffff800c428000//STACK_OFFSET_TYPE(stkptr)
> $6 = 0x1c1da278e0
> (gdb) p /x regs
> $7 = 0x55717394b3c0
> (gdb) p *(struct arm64_pt_regs *) 0x55717394b3c0
> Cannot access memory at address 0x55717394b3c0
> 
> For fix this, I think it must be add a condition
> "arm64_in_exception_text(stackframe.pc) && INSTACK(stackframe.fp, bt)" to avoid
> an invalid exception frame before transitioning to the process stack.
> 
> The patch file has been upload to attachment.
> Thanks for your review. I’m looking forward to your favourable reply!
> 
> Best regards,
> Qiwu

I cannot reproduce this using when I use "bt -S" with the "sp" address found in
the log.  When I do so, the backtrace is identical to when I enter "bt" alone, 
so I'm not clear on why yours is behaving differently?  

Is this a kdump-generated dumpfile?

Have you looked into why you get the "bt: WARNING: cannot determine 
starting stack frame for task ffffffcd74122000" message?  

You didn't show the results of your patch -- if you apply it, does the
backtrace get displayed correctly?  

Since the "bt -S" option is almost never used.  Would it be possible to
restrict your patch to fix/verify things in the section where it handles 
the bt->hp->sp setting?

   2555         } else if (bt->hp && bt->hp->esp) {
   2556                 if (arm64_on_irq_stack(bt->tc->processor, bt->hp->esp)) {
   2557                         arm64_set_irq_stack(bt);
   2558                         bt->flags |= BT_IRQSTACK;
   2559                 }
   2560                 stackframe.fp = GET_STACK_ULONG(bt->hp->esp - 8);
   2561                 stackframe.pc = bt->hp->eip ?
   2562                         bt->hp->eip : GET_STACK_ULONG(bt->hp->esp);
   2563                 stackframe.sp = bt->hp->esp + 8;
   2564                 bt->flags &= ~BT_REGS_NOT_FOUND;
   2565         }

It seems that you could check whether your stackframe.fp is larger than the stacktop
address, and for that matter what is the stackframe.pc that you see?

Dave 





More information about the Crash-utility mailing list