Bug in i386/i386/trap.c %gs handling on stable
dillon at apollo.backplane.com
Tue Dec 9 10:55:38 PST 2003
:> In i386/i386/trap.c if %gs is invalid... for example, a process with a
:> USER_LDT takes an interrupt while exiting, or if %gs is set
:> through procfs,
:> the fault check must occur regardless of the interrupt nesting
:> level because
:> mainline code does not push and load a %gs for the kernel.
:I don't quite get it. There'll be fault only when the kernel tries to
:load an invalid %gs. And there's only one place that the kernel would
:load a new %gs: during a context switch, which could not take place in
:an interrupt context.
Hmm. I think you are right. In FreeBSD-5 a context can occur at any
time which presumably is why the %gs test was moved to outside the
interrupt nesting level check.
In FreeBSD-4 a context switch will only occur outside of an interrupt
so I guess it can't happen. Well, that isn't entirely true... a
context switch has been known to happen inside interrupts in 4.x
but those are considered to be bugs :-).
In DragonFly an interrupt preemption causes a context switch, then
another switch back after the interrupt code finishes or blocks, which
is why the problem occured in DFly.
:> the situation with a process takes an interrupt while exiting and %fs is
:> set to a USER_LDT entry. I have not checked this, but if it is
:> true it would
:> be a problem in both -current and -stable for the exiting case.
:It's different for %fs, it holds a valid kernel segment at all time
:inside the kernel.
Hmm. But it still must save and restore %fs. If a user program
sets up a user LDT, loads %fs with a valid value, and then deletes the
user LDT, %fs will be bad.
The only thing that saves us in 4.x is the fact that the interrupt
nesting level will be 0 when the first interrupt restores %fs. That is,
it will have already decremented intr_nesting_level. It will take
the fault but properly deal with the consequences, and a nested interrupt
will be saving and restoring the kernel %fs that the first interrupt
In 5.x it looks a lot more fragile but I guess the same thing applies,
<dillon at backplane.com>
More information about the freebsd-stable