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);
next prev parent 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