segfault on jump from PLT

非 Y 不嫁゛ 提交于 2020-02-06 07:41:06

问题


I am trying to find the cause of a segfault, and narrowed it to the PLT using gdb's btrace. The segfault occurs during a jump from the PLT to the GOT, which I interpret to signify that the PLT became corrupted during execution. Based on the analysis presented below, is this interpretation correct? What are likely culprits for corruption of the PLT? Stack overflow? I believe that installing a watchpoint on the GOT address could be helpful in this instance. Would watch -l 0x55555562f048 be the correct approach? Other ideas for debugging are welcome.


For context, the segfault occurs during a call to strlen in function foo:

int foo(char * path, ...) {
    ...
    if (strlen(path) >= PATH_MAX) {

The corresponding lines of assembly are:

0x58114 <foo+212>    cmpq   $0x0,-0x4c8(%rbp)
0x5811c <foo+220>    jne    0x5812a <foo+234>
0x5811e <foo+222>    lea    0xb96fb(%rip),%rdi        # 0x111820
0x58125 <foo+229>    callq  0x376c0 <__ubsan_handle_nonnull_arg@plt>
0x5812a <foo+234>    mov    -0x4c8(%rbp),%rax
0x58131 <foo+241>    mov    %rax,%rdi
0x58134 <foo+244>    callq  0x37090 <strlen@plt>

First, path is compared to NULL (cmpq $0x0,-0x4c8(%rbp)), which I believe is solely added for ubsan instrumentation in this case. That branch was not followed, and the program jumped to <foo+234>, where it set up for the strlen call, by moving path to rax and then rdi, and finally calling strlen@plt. Running record btrace in gdb just before this produced this instruction history:

(gdb) record btrace
(gdb) c
136        0x00005555555ac114 <foo+212>:        cmpq   $0x0,-0x4c8(%rbp)
137        0x00005555555ac11c <foo+220>:        jne    0x5555555ac12a <foo+234>
138        0x00005555555ac12a <foo+234>:        mov    -0x4c8(%rbp),%rax
139        0x00005555555ac131 <foo+241>:        mov    %rax,%rdi
140        0x00005555555ac134 <foo+244>:        callq  0x55555558b090 <strlen@plt>
141        0x000055555558b090 <strlen@plt+0>:   jmpq   *0xa3fb2(%rip)  # 0x55555562f048 <strlen@got.plt>

Here, we see that path was not null, and so the program jumped to <foo+234>, and set up for the strlen call (mov, mov, callq <strlen@plt>). The final instruction executed was jmpq *0xa3fb2(%rip) to the entry for strlen in the GOT (strlen@got.plt), whereupon the program crashed and gdb lost context (reporting that it Cannot find bounds of current function).

来源:https://stackoverflow.com/questions/59698839/segfault-on-jump-from-plt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!