From owner-freebsd-stable@FreeBSD.ORG Tue Dec 9 10:55:38 2003 Return-Path: Delivered-To: freebsd-stable@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 91B6016A4CE for ; Tue, 9 Dec 2003 10:55:38 -0800 (PST) Received: from apollo.backplane.com (apollo.backplane.com [216.240.41.2]) by mx1.FreeBSD.org (Postfix) with ESMTP id CA1C143D37 for ; Tue, 9 Dec 2003 10:55:34 -0800 (PST) (envelope-from dillon@apollo.backplane.com) Received: from apollo.backplane.com (localhost [127.0.0.1]) hB9ItRiF074505; Tue, 9 Dec 2003 10:55:27 -0800 (PST) (envelope-from dillon@apollo.backplane.com) Received: (from dillon@localhost) by apollo.backplane.com (8.12.9p2/8.12.9/Submit) id hB9ItR6C074504; Tue, 9 Dec 2003 10:55:27 -0800 (PST) (envelope-from dillon) Date: Tue, 9 Dec 2003 10:55:27 -0800 (PST) From: Matthew Dillon Message-Id: <200312091855.hB9ItR6C074504@apollo.backplane.com> To: "Luoqi Chen" References: cc: stable@freebsd.org Subject: RE: Bug in i386/i386/trap.c %gs handling on stable X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Dec 2003 18:55:38 -0000 : :> 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