Ptrace with FSGSBASE
Bae, Chang Seok
chang.seok.bae at intel.com
Thu Mar 8 21:22:46 UTC 2018
I’m working on enabling FSGSBASE instructions [1, 2] in Linux kernel. The FSGSBASE instruction set allows
to read/write FS/GS base directly from any privilege. With that, any thread may have own FS/GS base
regardless of its selector. The reason I’m contacting you is to coordinate any legacy behavior that your tool chain
may rely on, before submitting our patches.
Currently, FS/GS base is reloaded from GDT/LDT if selector is not zero. With that, ptrace has such implications
on fs/gs set via SETREG* so far:
(1) If fs/gs only set
- to any nonzero value, fs_base/gs_base is fetched from GDT/LDT, when tracee resumes.
- to zero, current fs_base/gs_base is kept
(2) If fs_base/gs_base only set to any new,
- when fs/gs is zero, new fs_base/gs_base is set
- when fs/gs is nonzero, new value is ignored
and fs_base/gs_base is fetched from GDT/LDT, when tracee resumes
(3) If both fs/gs and fs_base/gs_base are set;
- fs/gs set to any nonzero, fs_base/gs_base fetched from
GDT/LDT entry of the new fs/gs (selector), when tracee resumes
- fs/gs set to zero, new fs_base/gs_base is set
Note. ptrace's SETREG* accepts user_regs_struct aligned data, where fs/gs and fs_base/gs_base entries are.
We prepared kernel patch set with following behaviors when FSGSBASE instructions are enabled.
(1) is taken as regarded as a legacy behavior; it will do the same
(2) & (3), (New) regardless of fs/gs value, new base value is always set
This new behavior is driven by that each thread’s FS/GS base is preserved during context switch.
More information about the rr-dev