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
).