Suppose I'm a ptracer. Wtf is supposed to happen when I write to
fs_base or gs_base?
Here are some schenarios:
1. I read fs_base using ptrace. I think I should get the actual
fs_base without any nonsense.
2. I read all the regs (PEEKUSER or whatever) and then write then all
back verbatim. At the very least, I think that if I do this
atomically using PTRACE_SETREGSET, the task's state needs to remain
unchanged. Since ptrace doesn't seem to have any real concept of
atomic register state changes right now (although we could add such a
thing for GETREGSET), it would be convenient if writing the unchanged
state back in numerical order using POKEUSER should also leave it
unchanged.
3. I write fs_base on a non-FSGSBASE system. I think it should have
the obvious effect of setting FSBASE to the value I wrote.
4. I write fs_base on an FSGSBASE system. I think it should have the
obvious effect of setting FSBASE to the value I wrote. It would be
nice if it behaved identically to #3 as well.
#3 that writing fs_base using ptrace, if it's set to a value that
doesn't match the base associated with the current selector, needs to
zero out fs.
#4 means that it should do the same on an fsgsbase system.
Due to the strange design of user_regs, fs_base and gs_base are
numerically below fs and gs, so #2 means that writing fs on an
FSGSBASE system shouldn't override a just-written fsbase value on an
FSGSBASE system. But writing fs on a non-FSGSBASE system needs to
override the just-written base.
But wouldn't users expect that writing a value into fs would actually
change the base even on FSGSBASE systems?
The best thing I've come up with so far is to have POKEUSER to fs and
gs have different behaviorf on FSGSBASE systems, which IMO sucks. On
the other hand, it wouldn't surprise me all that much if no one ever
does this in the first place.
See this, too:
https://lkml.org/lkml/2007/11/21/82
--
Andy Lutomirski
AMA Capital Management, LLC