public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: "H. Peter Anvin" <hpa@zytor.com>
To: Samuel Thibault <samuel.thibault@labri.fr>,
	linux-kernel@vger.kernel.org,
	Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>,
	x86@kernel.org, olivier.aumage@inria.fr, yannick.martin@inria.fr
Subject: Re: X86_64 BUG: missing FS/GS LDT reload on fork()
Date: Fri, 23 Apr 2010 11:01:05 -0700	[thread overview]
Message-ID: <4BD1E061.8030605@zytor.com> (raw)
In-Reply-To: <20100423170449.GV4997@const.bordeaux.inria.fr>

[-- Attachment #1: Type: text/plain, Size: 1086 bytes --]

On 04/23/2010 10:04 AM, Samuel Thibault wrote:
> Hello,
> 
> I have an issue with FS/GS LDT reload in the child of fork(). The
> attached testcase fails quite often.  It sets an LDT entry up, uses
> prctl to set gs's base to a 64bit value, then loads gs with the LDT
> entry. The LDT entry is now in effect. After a fork call, the LDT entry
> is not in effect any more, the 64bit base is back!
> 

Okay... I have to say that I'm more than a bit confused why you're doing
this, but the __switch_no code in process_64.c has the following:

                /*
                 * Check if the user used a selector != 0; if yes
                 *  clear 64bit base, since overloaded base is always
                 *  mapped to the Null selector
                 */
                if (fsindex)
                        prev->fs = 0;

[and the same for gs]

However, copy_thread() doesn't have the equivalent code, and __switch_to
clearly expects that to be maintained as an invariant -- it doesn't
check on entry, only on exit.

The following patch looks like it should address that.

	-hpa

[-- Attachment #2: diff --]
[-- Type: text/plain, Size: 652 bytes --]

diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index dc9690b..17cb329 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -276,12 +276,12 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
 
 	set_tsk_thread_flag(p, TIF_FORK);
 
-	p->thread.fs = me->thread.fs;
-	p->thread.gs = me->thread.gs;
 	p->thread.io_bitmap_ptr = NULL;
 
 	savesegment(gs, p->thread.gsindex);
+	p->thread.gs = p->thread.gsindex ? 0 : me->thread.gs;
 	savesegment(fs, p->thread.fsindex);
+	p->thread.fs = p->thread.fsindex ? 0 : me->thread.fs;
 	savesegment(es, p->thread.es);
 	savesegment(ds, p->thread.ds);
 

  reply	other threads:[~2010-04-23 18:01 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-23 17:04 X86_64 BUG: missing FS/GS LDT reload on fork() Samuel Thibault
2010-04-23 18:01 ` H. Peter Anvin [this message]
2010-04-23 23:01   ` Samuel Thibault
2010-04-23 23:42   ` [tip:x86/urgent] x86-64: Clear a 64-bit FS/GS base on fork if selector is nonzero tip-bot for H. Peter Anvin
2010-04-23 23:51   ` tip-bot for H. Peter Anvin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4BD1E061.8030605@zytor.com \
    --to=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=olivier.aumage@inria.fr \
    --cc=samuel.thibault@labri.fr \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    --cc=yannick.martin@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox