lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 13 Sep 2006 17:25:53 -0700
From:	Zachary Amsden <zach@...are.com>
To:	Alan Cox <alan@...rguk.ukuu.org.uk>
Cc:	Jeremy Fitzhardinge <jeremy@...p.org>,
	Arjan van de Ven <arjan@...radead.org>,
	Linus Torvalds <torvalds@...l.org>,
	Ingo Molnar <mingo@...e.hu>, Andi Kleen <ak@...e.de>,
	"Eric W. Biederman" <ebiederm@...ssion.com>,
	Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
	Michael A Fetterman <Michael.Fetterman@...cam.ac.uk>
Subject: Re: Assignment of GDT entries

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
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ