-
Notifications
You must be signed in to change notification settings - Fork 572
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
32bit tls is broken on 5.9-rc1 #2642
Comments
Adding |
with |
Per the discussion on LKML, as of 5.9 we need to preserve fsbase/gsbase when running on a 64 bit kernel for both 32 and 64 bit tracees (we're currently only doing that, and it was previously only required, for 64 bit tracees). |
When the GPRs are manipulated through PTRACE_GETREGS/PTRACE_SETREGS, whether the register set is the 32 bit user_regs_struct or the 64 bit user_regs_struct depends on whether rr is a 32 bit or 64 bit program. But when they're manipulated through PTRACE_GETREGSET/PTRACE_SETREGSET with the NT_PRSTATUS regset, it depends on whether the *tracee* is a 32 bit or 64 bit program. Starting with kernel 5.9, if a 64 bit rr PTRACE_SETREGS a 32 bit tracee the fs/gsbase values in that user_regs_struct are used. This is a problem because we don't track them and thus they're always zero, regardless of what the correct value is. See LKML "x86/cpu fsgsbase breaks TLS in 32 bit rr tracees on a 64 bit system" for more discussion. If we use PTRACE_SETREGSET we can pass in the 32 bit version of user_regs_struct and the kernel will figure out the correct fs/gsbase as before. It's still more convenient to use PTRACE_GETREGS rather than PTRACE_GETREGSET so we can be sure where the CS register is in memory for testing whether we have a 64/32 bit process, so that and the conversion code stick around. Fixes #2642 (again).
This is needed as of kernel 5.9. Fixes rr-debugger#2642.
When the GPRs are manipulated through PTRACE_GETREGS/PTRACE_SETREGS, whether the register set is the 32 bit user_regs_struct or the 64 bit user_regs_struct depends on whether rr is a 32 bit or 64 bit program. But when they're manipulated through PTRACE_GETREGSET/PTRACE_SETREGSET with the NT_PRSTATUS regset, it depends on whether the *tracee* is a 32 bit or 64 bit program. Starting with kernel 5.9, if a 64 bit rr PTRACE_SETREGS a 32 bit tracee the fs/gsbase values in that user_regs_struct are used. This is a problem because we don't track them and thus they're always zero, regardless of what the correct value is. See LKML "x86/cpu fsgsbase breaks TLS in 32 bit rr tracees on a 64 bit system" for more discussion. If we use PTRACE_SETREGSET we can pass in the 32 bit version of user_regs_struct and the kernel will figure out the correct fs/gsbase as before. It's still more convenient to use PTRACE_GETREGS rather than PTRACE_GETREGSET so we can be sure where the CS register is in memory for testing whether we have a 64/32 bit process, so that and the conversion code stick around. Fixes rr-debugger#2642 (again).
e.g.
simple_32
will segfault on a TLS access when recording under rrbisected to https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=v5.8&id=b745cfba44c152c34363eea9e052367b6b1d652b
The text was updated successfully, but these errors were encountered: