Messages in this thread | | | From | Andy Lutomirski <> | Date | Wed, 24 Jun 2020 17:54:44 -0700 | Subject | Re: [PATCH 3/3] x86/ptrace: Fix 32-bit PTRACE_SETREGS vs fsbase and gsbase |
| |
On Wed, Jun 24, 2020 at 3:50 PM Andy Lutomirski <luto@kernel.org> wrote: > > Debuggers expect that doing PTRACE_GETREGS, then poking at a tracee > and maybe letting it run for a while, then doing PTRACE_SETREGS will > put the tracee back where it was. In the specific case of a 32-bit > tracer and tracee, the PTRACE_GETREGS/SETREGS data structure doesn't > have fs_base or gs_base fields, so FSBASE and GSBASE fields are > never stored anywhere. Everything used to still work because > nonzero FS or GS would result full reloads of the segment registers > when the tracee resumes, and the bases associated with FS==0 or > GS==0 are irrelevant to 32-bit code. > > Adding FSGSBASE support broke this: when FSGSBASE is enabled, FSBASE > and GSBASE are now restored independently of FS and GS for all tasks > when context-switched in. This means that, if a 32-bit tracer > restores a previous state using PTRACE_SETREGS but the tracee's > pre-restore and post-restore bases don't match, then the tracee is > resumed with the wrong base. > > Fix it by explicitly loading the base when a 32-bit tracer pokes FS > or GS on a 64-bit kernel.
> diff --git a/tools/testing/selftests/x86/fsgsbase_restore.c b/tools/testing/selftests/x86/fsgsbase_restore.c > new file mode 100644 > index 000000000000..70502a708dee > --- /dev/null > +++ b/tools/testing/selftests/x86/fsgsbase_restore.c
> + if (false && syscall(SYS_modify_ldt, 1, &desc, sizeof(desc)) == 0) {
Whoops. That 'false &&' shouldn't be there. Want a v2?
| |