From: Zachary Amsden <zach@vmware.com>
To: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Jeremy Fitzhardinge <jeremy@goop.org>,
Arjan van de Ven <arjan@infradead.org>,
Linus Torvalds <torvalds@osdl.org>, Ingo Molnar <mingo@elte.hu>,
Andi Kleen <ak@suse.de>,
"Eric W. Biederman" <ebiederm@xmission.com>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Michael A Fetterman <Michael.Fetterman@cl.cam.ac.uk>
Subject: Re: Assignment of GDT entries
Date: Wed, 13 Sep 2006 17:25:53 -0700 [thread overview]
Message-ID: <4508A191.1060203@vmware.com> (raw)
In-Reply-To: <1158183322.16902.8.camel@localhost.localdomain>
Alan Cox wrote:
> Ar Mer, 2006-09-13 am 13:59 -0700, ysgrifennodd Zachary Amsden:
>
>> TLS #3 overlaps BIOS 0x40, but code which calls borken APM / PnP BIOS
>> and sets up protected mode 0x40 GDT segment does so by swapping out the
>> TLS segment with the identity simulation of physical 0x400 offset,
>> swapping it back afterwards. Short of bugs in that code (which there
>> are, btw), you shouldn't need to be concerned with it.
>>
>
> Care to elucidate ?
>
I believe the current max use case for GDT descriptors is Wine. Wine
compiled against TLS glibc uses entry zero for libc, and allocates
another GDT entry for the first thread created by NTDLL (although I have
no idea why, since there is fallback code to use LDT allocation instead,
and all subsequent allocations happen via the LDT - perhaps some kernel
mode DLL thing insists on having the first thread in the GDT?) DOSemu
by the way, only uses the LDT.
But there is no reason userspace can't allocate 3 TLS descriptors in the
GDT per thread. If it did, the overlap between 0x40 (descriptor #8,
real mode BIOS simulation of physical address 0x400, BIOS data area)
causes a problem. Fortunately, APM and PnP take care to fix this by
swapping in and out the descriptors. Unfortunately, they don't get it
quite right.
Selected code snippets (PnP):
/*
* PnP BIOSes are generally not terribly re-entrant.
* Also, don't rely on them to save everything correctly.
*/
if(pnp_bios_is_utter_crap)
return PNP_FUNCTION_NOT_SUPPORTED;
cpu = get_cpu();
save_desc_40 = get_cpu_gdt_table(cpu)[0x40 / 8];
get_cpu_gdt_table(cpu)[0x40 / 8] = bad_bios_desc; <---- set up
fake BIOS descriptor for 0x400
/* On some boxes IRQ's during PnP BIOS calls are deadly. */
spin_lock_irqsave(&pnp_bios_lock, flags);
... now inline assembler
"pushl %%fs\n\t"
"pushl %%gs\n\t"
"pushfl\n\t"
"movl %%esp, pnp_bios_fault_esp\n\t"
"movl $1f, pnp_bios_fault_eip\n\t"
"lcall %5,%6\n\t"
"1:popfl\n\t"
"popl %%gs\n\t" <---- (**)
"popl %%fs\n\t" <---- (**)
... now restore original GDT descriptor back
spin_unlock_irqrestore(&pnp_bios_lock, flags);
get_cpu_gdt_table(cpu)[0x40 / 8] = save_desc_40;
put_cpu();
But it is too late - damage is already done (at **), since %fs or %gs
could have had a reference to TLS descriptor #3, and they get reloaded
_before_ the GDT is restored. Thus any userspace process that uses TLS
descriptor #3 in FS or GS and makes a BIOS call to PnP may get corrupted
data loaded into the hidden state of FS / GS selectors.
APM has a similar problem. Both are easily fixable, but there has been
too much flux in this area recently to get a stable patch for these
problems, and the problems are exceedingly unlikely, since I don't know
of a single userspace program using TLS descriptor #3, much less one
that makes use of APM or PnP facilities. There is the possibility
however, that such a program could sleep, run the idle thread, which
makes a call into some of these BIOS facilities, and then reschedules
the same program thread - which means FS/GS never get reloaded, thus
maintaining their corrupted values. It is worth fixing, just not a high
priority. I had a patch that fixed both APM and PnP at one time, but it
is covered with mold and now looks like a science experiment. Shall I
apply disinfectant?
Zach
next prev parent reply other threads:[~2006-09-14 0:26 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-09-13 18:58 Assignment of GDT entries Jeremy Fitzhardinge
2006-09-13 19:16 ` Arjan van de Ven
2006-09-13 20:00 ` Alan Cox
2006-09-13 20:02 ` Jeremy Fitzhardinge
2006-09-13 20:20 ` Jeremy Fitzhardinge
2006-09-13 20:59 ` Zachary Amsden
2006-09-13 21:15 ` Jeremy Fitzhardinge
2006-09-13 21:35 ` Alan Cox
2006-09-14 0:25 ` Zachary Amsden [this message]
2006-09-14 1:40 ` Stephen Rothwell
2006-09-14 13:03 ` Alan Cox
2006-09-13 19:55 ` linux-os (Dick Johnson)
2006-09-13 20:08 ` Jeremy Fitzhardinge
2006-09-13 20:32 ` linux-os (Dick Johnson)
2006-09-13 21:21 ` Linus Torvalds
2006-09-13 21:47 ` Jeremy Fitzhardinge
2006-09-13 22:05 ` Linus Torvalds
2006-09-13 22:22 ` Jeremy Fitzhardinge
2006-09-14 6:00 ` Andi Kleen
-- strict thread matches above, loose matches on Subject: below --
2006-09-14 3:23 Albert Cahalan
2006-09-14 6:11 ` Jeremy Fitzhardinge
2006-09-14 4:06 Albert Cahalan
2006-09-14 4:44 ` Eric W. Biederman
2006-09-14 6:19 ` Albert Cahalan
2006-09-14 6:28 ` Zachary Amsden
2006-09-14 7:12 ` Albert Cahalan
2006-09-14 7:24 ` Zachary Amsden
2006-09-14 6:29 ` Jeremy Fitzhardinge
2006-09-15 7:55 Mikael Pettersson
2006-09-15 8:20 ` Jeremy Fitzhardinge
2006-09-15 8:58 ` Mikael Pettersson
2006-09-15 18:27 ` Jeremy Fitzhardinge
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=4508A191.1060203@vmware.com \
--to=zach@vmware.com \
--cc=Michael.Fetterman@cl.cam.ac.uk \
--cc=ak@suse.de \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=arjan@infradead.org \
--cc=ebiederm@xmission.com \
--cc=jeremy@goop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=torvalds@osdl.org \
/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