[mod: The first message would''ve been rejected on the grounds "no security related information", but it gives ME a warm feeling too, so I''m allowing it to piggyback on the announcement of the "fix". Note that Linux-2.1.63 simply implements a fix for the problem, instead of applying this fix, upgrading to 2.1.63 might be an option for you. Linus indicated that this fix WILL be moving into 2.0.3x . Case closed? Oh, and allow me to aplogise in public to all that I told that I did not believe them when they told me that P6 processors (P-Pro and P-II) have a writable microcode feature. They do. (Assignment for Crypto-101: Decode the encrypted microcode that is avaible at http://www.sandpile.org/80x86/mcupdate/update32.zip --16 hours) I mentioned that I expected Pentium overdrives to be affected. Several people have confirmed that they aren''t. Odd. The fix relies on the CPUID information, do they get detected as having the F00F bug? -- REW] ------------------------------------------------------------------ Related to the "F0 OF C7 C8" bug, from http://support.intel.com/support/processors/pentium/ppiie/index.htm The execution of that reported instruction sequence causes systems with Pentium processors and Pentium processor with MMX technology to hang instead of terminating the application. This hang condition is observed on multiple operating systems (DOS*, Windows* 95, Windows* NT, and Linux*) when used with this instruction sequence. Intel has reproduced the behavior. Linux got equal billing with all of MS''s OS''s (and quasi-OS''s). Intel''s acknowledgement of Linux gave me a fuzzy. (The * is footnoted as "These trademarks are property of their respective owners." That now means Linus in our community. Thanks to all involved parties for helping make that come true.) --Up. ------------------------------------------------------------------ Forwarding headers mangle patches. Mind the gap. --Up. ------- start of forwarded message (RFC 934 encapsulation) ------- From: Aleph One <aleph1@DFW.NET> Sender: Bugtraq List <BUGTRAQ@NETSPACE.ORG> To: BUGTRAQ@NETSPACE.ORG Subject: Linux F00F Patch Date: Wed, 12 Nov 1997 18:45:15 -0600 Reply-To: Aleph One <aleph1@DFW.NET> This are the relevant parts of the linux kernel 2.1.63 patch that fix the Pentium bug that Alan mentioned. Aleph One / aleph1@dfw.net http://underground.org/ KeyID 1024/948FD6B5 Fingerprint EE C9 E8 AA CB AF 09 61 8C 39 EA 47 A8 6A B8 01 diff -u --recursive --new-file v2.1.62/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c - --- v2.1.62/linux/arch/i386/kernel/setup.c Tue Sep 23 16:48:46 1997 +++ linux/arch/i386/kernel/setup.c Wed Nov 12 11:09:56 1997 @@ -42,6 +42,7 @@ char x86_mask = 0; /* set by kernel/head.S */ int x86_capability = 0; /* set by kernel/head.S */ int fdiv_bug = 0; /* set if Pentium(TM) with FP bug */ +int pentium_f00f_bug = 0; /* set if Pentium(TM) with F00F bug */ int have_cpuid = 0; /* set if CPUID instruction works */ char x86_vendor_id[13] = "unknown"; @@ -359,6 +360,7 @@ "fdiv_bug\t: %s\n" "hlt_bug\t\t: %s\n" "sep_bug\t\t: %s\n" + "pentium_f00f_bug\t\t: %s\n" "fpu\t\t: %s\n" "fpu_exception\t: %s\n" "cpuid\t\t: %s\n" @@ -367,6 +369,7 @@ CD(fdiv_bug) ? "yes" : "no", CD(hlt_works_ok) ? "no" : "yes", sep_bug ? "yes" : "no", + pentium_f00f_bug ? "yes" : "no", CD(hard_math) ? "yes" : "no", (CD(hard_math) && ignore_irq13) ? "yes" : "no", diff -u --recursive --new-file v2.1.62/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c - --- v2.1.62/linux/arch/i386/kernel/traps.c Sun Sep 7 13:10:42 1997 +++ linux/arch/i386/kernel/traps.c Wed Nov 12 11:09:56 1997 @@ -413,6 +413,51 @@ #endif /* CONFIG_MATH_EMULATION */ +static struct +{ + short limit __attribute__((packed)); + void * addr __attribute__((packed)); + short __pad __attribute__((packed)); +} idt_d; + +void * idt2; + +__initfunc(void trap_init_f00f_bug(void)) +{ + pgd_t * pgd; + pmd_t * pmd; + pte_t * pte; + unsigned long twopage; + + printk("moving IDT ... "); + + twopage = (unsigned long) vmalloc (2*PAGE_SIZE); + + idt2 = (void *)(twopage + 4096-7*8); + + memcpy(idt2,&idt,sizeof(idt)); + + idt_d.limit = 256*8-1; + idt_d.addr = idt2; + idt_d.__pad = 0; + + __asm__ __volatile__("\tlidt %0": "=m" (idt_d)); + + /* + * Unmap lower page: + */ + pgd = pgd_offset(current->mm, twopage); + pmd = pmd_offset(pgd, twopage); + pte = pte_offset(pmd, twopage); + + pte_clear(pte); + flush_tlb_all(); + + printk(" ... done\n"); +} + + + __initfunc(void trap_init(void)) { int i; diff -u --recursive --new-file v2.1.62/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c - --- v2.1.62/linux/arch/i386/mm/fault.c Wed Oct 15 16:04:23 1997 +++ linux/arch/i386/mm/fault.c Wed Nov 12 11:09:55 1997 @@ -74,6 +74,25 @@ return 0; } +asmlinkage void divide_error(void); +asmlinkage void debug(void); +asmlinkage void nmi(void); +asmlinkage void int3(void); +asmlinkage void overflow(void); +asmlinkage void bounds(void); +asmlinkage void invalid_op(void); + +asmlinkage void do_divide_error (struct pt_regs *, unsigned long); +asmlinkage void do_debug (struct pt_regs *, unsigned long); +asmlinkage void do_nmi (struct pt_regs *, unsigned long); +asmlinkage void do_int3 (struct pt_regs *, unsigned long); +asmlinkage void do_overflow (struct pt_regs *, unsigned long); +asmlinkage void do_bounds (struct pt_regs *, unsigned long); +asmlinkage void do_invalid_op (struct pt_regs *, unsigned long); + +extern int * idt2; +extern int pentium_f00f_bug; + /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate @@ -170,6 +189,46 @@ goto out; } + printk("<%p/%p>\n", idt2, (void *)address); + /* + * Pentium F0 0F C7 C8 bug workaround: + */ + if ( pentium_f00f_bug && (address >= (unsigned long)idt2) && + (address < (unsigned long)idt2+256*8) ) { + + void (*handler) (void); + int nr = (address-(unsigned long)idt2)/8; + unsigned long low, high; + + low = idt[nr].a; + high = idt[nr].b; + + handler = (void (*) (void)) ((low&0x0000ffff) | (high&0xffff0000)); + printk("<handler %p... ", handler); + unlock_kernel(); + + if (handler==divide_error) + do_divide_error(regs,error_code); + else if (handler==debug) + do_debug(regs,error_code); + else if (handler==nmi) + do_nmi(regs,error_code); + else if (handler==int3) + do_int3(regs,error_code); + else if (handler==overflow) + do_overflow(regs,error_code); + else if (handler==bounds) + do_bounds(regs,error_code); + else if (handler==invalid_op) + do_invalid_op(regs,error_code); + else { + printk("INVALID HANDLER!\n"); + for (;;) __cli(); + } + printk("... done>\n"); + goto out; + } + /* Are we prepared to handle this kernel fault? */ if ((fixup = search_exception_table(regs->eip)) != 0) { printk(KERN_DEBUG "%s: Exception at [<%lx>] cr2=%lx (fixup: %lx)\n", @@ -193,6 +252,7 @@ flush_tlb(); goto out; } + if (address < PAGE_SIZE) printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); else diff -u --recursive --new-file v2.1.62/linux/include/asm-i386/bugs.h linux/include/asm-i386/bugs.h - --- v2.1.62/linux/include/asm-i386/bugs.h Thu Sep 11 09:02:24 1997 +++ linux/include/asm-i386/bugs.h Wed Nov 12 11:09:55 1997 @@ -166,6 +166,32 @@ } } +/* + * All current models of Pentium and Pentium with MMX technology CPUs + * have the F0 0F bug, which lets nonpriviledged users lock up the system: + */ + +extern int pentium_f00f_bug; + +__initfunc(static void check_pentium_f00f(void)) +{ + /* + * Pentium and Pentium MMX + */ + printk("checking for F00F bug ..."); + if(x86==5 && !memcmp(x86_vendor_id, "GenuineIntel", 12)) + { + extern void trap_init_f00f_bug(void); + + printk(KERN_INFO "\nIntel Pentium/[MMX] F0 0F bug detected - turning on workaround.\n"); + pentium_f00f_bug = 1; + trap_init_f00f_bug(); + } else { + printk(KERN_INFO " no F0 0F bug in this CPU, great!\n"); + pentium_f00f_bug = 0; + } +} + __initfunc(static void check_bugs(void)) { check_tlb(); @@ -173,5 +199,6 @@ check_hlt(); check_popad(); check_amd_k6(); + check_pentium_f00f(); system_utsname.machine[1] = ''0'' + x86; } ------- end -------