Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Dec 2003 10:55:27 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        "Luoqi Chen" <lchen@briontech.com>
Cc:        stable@freebsd.org
Subject:   RE: Bug in i386/i386/trap.c %gs handling on stable
Message-ID:  <200312091855.hB9ItR6C074504@apollo.backplane.com>
References:  <AHEKICEOIHLOGINAFIINCEGMCBAA.lchen@briontech.com>

next in thread | previous in thread | raw e-mail | index | archive | help

:
:> 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.
:..
:-lq 

    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
    loaded up.

    In 5.x it looks a lot more fragile but I guess the same thing applies,
    just barely.

					-Matt
					Matthew Dillon 
					<dillon@backplane.com>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200312091855.hB9ItR6C074504>