aboutsummaryrefslogtreecommitdiff
path: root/gdbserver/gdbthread.h
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2021-01-20 16:29:30 +0100
committerTom de Vries <tdevries@suse.de>2021-01-20 16:29:30 +0100
commit037e8112b9794a633248e5aa5943f3be273e0a20 (patch)
treed1a60fb8935822581e8413e5b401477bc56101fd /gdbserver/gdbthread.h
parent4bd7c90276a11ee2f43c6bbe62f2379f3a225234 (diff)
downloadgdb-037e8112b9794a633248e5aa5943f3be273e0a20.zip
gdb-037e8112b9794a633248e5aa5943f3be273e0a20.tar.gz
gdb-037e8112b9794a633248e5aa5943f3be273e0a20.tar.bz2
[gdb/server] Don't overwrite fs/gs_base with -m32
Consider a minimal test-case test.c: ... int main (void) { return 0; } ... compiled with -m32: ... $ gcc test.c -m32 ... When running the exec using gdbserver on openSUSE Factory (currently running a linux kernel version 5.10.5): ... $ gdbserver localhost:12345 a.out ... to which we connect in a gdb session, we run into a segfault in the inferior: ... $ gdb -batch -q -ex "target remote localhost:12345" -ex continue Program received signal SIGSEGV, Segmentation fault. 0xf7dd8bd2 in init_cacheinfo () at ../sysdeps/x86/cacheinfo.c:761 ... The segfault is caused by gdbserver overwriting $gs_base with 0 using PTRACE_SETREGS. After it is overwritten, the next use of $gs in the inferior will trigger the segfault. Before linux kernel version 5.9, the value used by PTRACE_SETREGS for $gs_base was ignored, but starting version 5.9, the linux kernel has support for intel architecture extension FSGSBASE, which allows users to modify $gs_base, and consequently PTRACE_SETREGS can no longer ignore the $gs_base value. The overwrite of $gs_base with 0 is done by a memset in x86_fill_gregset, which was added in commit 9e0aa64f551 "Fix gdbserver qGetTLSAddr for x86_64 -m32". The memset intends to zero-extend 32-bit registers that are tracked in the regcache to 64-bit when writing them into the PTRACE_SETREGS data argument. But in addition, it overwrites other registers that are not tracked in the regcache, such as $gs_base. Fix the segfault by redoing the fix from commit 9e0aa64f551 in minimal form. Tested on x86_64-linux: - openSUSE Leap 15.2 (using kernel version 5.3.18): - native - gdbserver -m32 - -m32 - openSUSE Factory (using kernel version 5.10.5): - native - m32 gdbserver/ChangeLog: 2021-01-20 Tom de Vries <tdevries@suse.de> * linux-x86-low.cc (collect_register_i386): New function. (x86_fill_gregset): Remove memset. Use collect_register_i386.
Diffstat (limited to 'gdbserver/gdbthread.h')
0 files changed, 0 insertions, 0 deletions