Welcome to denMike's tiny page!
Home
Guestbook
Contact
 
Husky
 
Corona virus
Electronics
Fantasy
mtech.dk
Programming
  Resources in .exe Files

  Pascal Runtime Error 200

  The Pentium F0 bug

  Number Printing Routing

  Using the IOE Interrupt

 
Software
Space
Tilbud
Various Links
 
USA 2001
ISU MSS03
USA 2006
South Africa 2008


Last updated: May 3rd, 1999, 1999
(Uploaded November 23th, 1997)
The Pentium-F0 Bug.

Contents of this document
Which CPUs Have the Bug?
Description of the Bug
How Do I Execute the Bug?
The Solution
The Program
The EXE-file
List of Other Well-known Pentium-bugs
Links

Which CPUs Have the Bug?
This exact bug is only reported on Pentium Classic (P54C) and Pentium MMX (P55C) CPUs. This bug is therefore not found on Pentium Pro, Pentium II, K6, and Cyrix M1/M2. It ought to be mentioned, that the Cyrix-CPUs have a related bug.

Description of the Bug.
The Pentium-F0 bug is OS-independent, which means, that it will trash ANY OS, including OS/2, Windows NT, Windows 95, and Linux, all of which is thought of as 'safe' OS'es (they won't crash).

Rumours (which are a bit overstated) says, that the CPUs will burn, and be unable to reboot (= dead CPU). This hasn't happened for me however. A press on RESET solves the problem.

This means, that the average Windows 95 user won't notice a big difference (it crash every other time anyway). The real problem is found at an ISP (Internet Service Provider), who will get into serious trouble if his server dies, which seems to be piece of cake for a hacker (especially with all the security-bugs found in internet-software).

There has been written a fix for Linux, which has been included in the Linux kernel since v. 2.0.32pre4 and 2.1.63. It checks if the CPU is a bugged Pentium while loading, and if so, installs the protection. (I don't know how it works yet, however). This fix were made in less than a week from the bug was first reported. I wonder how long the WINtel-people have to use to do the same :)

Some people says, that the power consumption of the CPU falls to almost zero, but I haven't been able to verify it yet.

How Do I Execute the Bug?
The bug is the result of an invalid instruction. First you'll LOCK the bus and thereafter run invalid/unimplemented variants of the CMPXHG8 instruction. This requires no special permissions to run, it works fine with average-joe-userspace permissions. I have verified this, it works.

The instruction doesn't make sense at all. If you were supposed to analyse the instruction it would end up with something like this:

CMPXHG8 EDX:EAX,EAX
That is, compare and eventually exchange the 64-bit value in EDX:EAX with the 32-bit value in EAX.

Therefore normal software will NOT execute the instruction, but evil software can crash your computer via the net. It can only crash systems, which allow you to run your own programs on them, e.g. via ActiveX, a demonstration component is shown in the end of this paragraph.

When the instruction is executed the INT06-handler should be called and take care of the problem. The problem is though, that the system crashes while INT06 is called!

There is a build-in INT06-handler in OS/2, Windows NT, Windows 95, and Linux, which is supposed to catch invalid instructions. Therefore you can try to run this little program if you run either of these systems:

Create a file, and insert the following 4 characters with your favorite editor:

0F0h, 0Fh, 0C7h, 0C8h
call it CRASH.COM, and run the program. Your system will now crash, if you run with a bugged CPU under OS/2, Windows NT, Windows 95, or Linux. If you run with another OS, which doesn't have an INT06-handler (e.g. DOS) with e.g. a K6, you system will crash anyway, simply because you try to run an invalid instruction.

(CRASH.COM has been tested with NT 4.0 build 1381 running on a Pentium 166 MHz, non-MMX).

If you're running Windows with Microsoft Internet Explorer 3.0+, with ActiveX enabled, you can try to crash your Pentium Classic/MMX computer using the following ActiveX-form (you won't see the form if you're using a browser that don't support ActiveX, and hopefully you don't ;)

Here's the form (if your browser supports ActiveX):

The Solution.
The system crashes while the INT06-handler is called, but you can apparently use a work-around. Simply let the INT06-handler's entry in the IDT (Interrupt Descriptor Table) create a page-fault, and then take care of the problem from there.

The Program.
This is a modified version of the program I posted in the Danish Fido-net echo called HARDSOFT_R23.PUB.

This program runs perfectly well under DOS 5+ on any 80386+ CPU.

Source:

;-----------------------------------------------------------------------------
; Assembler directives
;-----------------------------------------------------------------------------
.xlist           ; disable list file
.286

;-----------------------------------------------------------------------------
; Macros
;-----------------------------------------------------------------------------
LoadAll MACRO
  db    0Fh,05h  ; LoadAll is an undocumented opcode on 80286, some 80386,
                 ; and some early i486s. Support for this instruction has
                 ; been dropped with the i486.
                 ; Therefore we can use this opcode to verify, that our
                 ; INT06-handler works.
ENDM

F0Bug MACRO
  db    0F0h,0Fh,0C7h,0C8h  ; This instruction will trash any Intel Pentium
                            ; (Classic and MMX).
ENDM                                                                  
                                                                      
PrintMsg MACRO Msg                                           
  mov          ah,9
  mov          dx,offset Msg
  int          21h                                                   
ENDM

.list
;-----------------------------------------------------------------------------
; Dummy segments
;-----------------------------------------------------------------------------
INTSEG segment at 0

  org          6*4

  INT06        dd  ?
INTSEG ends

;-----------------------------------------------------------------------------
; Data segment
;-----------------------------------------------------------------------------
_DATA segment use16 para public 'DATA'

;-----------------------------------------------------------------------------
; Misc data storage.
;-----------------------------------------------------------------------------
  NumInts      dw 0   ; Number of times int 6 has been called
  OrigINT06    dd 0   ; Temp holding spot for INT06 vector

;-----------------------------------------------------------------------------
; String messages used for formatting the screen output
;-----------------------------------------------------------------------------
  CRLFMsg      db 0dh,0ah,24h
  WelcomeMsg   db "This program tests your CPU for the Pentium-F0 bug.",0dh,0ah
               db "NOTE: This program will crash ANY Pentium Classic/MMX "
               db "system.",0dh,0ah,24h
  PressAKeyMsg db "Press SPACE to continue, or any other key to quit...",24h
  LoadAllMsg   db "Testing the LoadAll-instruction",0dh,0ah,24h
  F0Msg        db "Now testing for the F0-bug:",0dh,0ah,0dh,0ah,24h
  ErrorMsg     db "FAILED: Your CPU has the bug :(  (PRESS RESET)",24h
  HappyMsg     db "PASSED: You CPU doesn't have this bug :)",24h
  IntMsg       db 0dh,"[Int 6 called ",24h                   
  IntMsg2      db " time(s)] - ",24h
_DATA ENDS

;-----------------------------------------------------------------------------
; Beginning of main code segment
;-----------------------------------------------------------------------------
_TEXT	segment para public use16 'CODE'
  ASSUME CS:_TEXT, DS:_DATA, ES:_DATA, SS:STACKSEG
;-----------------------------------------------------------------------------
; Code starts here
; * Set up stack
;-----------------------------------------------------------------------------
  OPCODE proc	far
  mov   ax,seg STACKSEG    ; setup stack segment
  mov   ss,ax
  mov   sp,size StackPtr
  xor   ax,ax              ; clear it
  pushf
  push  ds                 ; save far return on stack
  push  ax

;-----------------------------------------------------------------------------
; * Disable interrupts during this test
; * Set up data segments
;-----------------------------------------------------------------------------
  cli                           ; disable interrupts
  mov   ax,seg _DATA            ; get data segment
  mov   ds,ax
  mov   es,ax

;-----------------------------------------------------------------------------
; Install INT06 (Invalid opcode) exception handler
;-----------------------------------------------------------------------------
@@:
  push  es                      ; save
  mov   ax,seg INTSEG
  mov   es,ax
  mov   ax,offset OurINT6       ; get pointer to our INT06 handler
  mov   dx,cs                   ; get our code segment
  xchg  ax,word ptr es:INT06    ; swap 'em
  xchg  dx,word ptr es:INT06[2] ; swap vector
  mov   word ptr OrigINT06,ax   ; save original vector
  mov   word ptr OrigINT06[2],dx; vector now saved
  pop   es                      ; restore original segment

;-----------------------------------------------------------------------------
; Test for the F0-bug. First we'll warn the user, that the system might crash.
; Then we'll try to see if our INT06-handler works by calling the
; LOADALL-instruction. Then we'll call the F0-bug.
;-----------------------------------------------------------------------------
  PrintMsg  CRLFMsg
  PrintMsg  WelcomeMsg          ; print Welcome message, ..
  PrintMsg  CRLFMsg
  PrintMsg  PressAKeyMsg        ; .. warn the user, ..
  xor       ah,ah
  int       16h
  cmp       ax,3920h
  jc        Exit                ; .. and let him quit

  PrintMsg  CRLFMsg             ; test the LOADALL-instruction
  PrintMsg  CRLFMsg
  call      _PNumInts
  PrintMsg  LoadAllMsg

  mov       dx,offset NoLoadAll ; set destination location
  LoadAll

NoLoadAll:
  call      _PNumInts
  PrintMsg  F0Msg
  PrintMsg  ErrorMsg            ; let's suppose, that the system dies

  mov       dx,offset NoF0Bug   ; set destination location
  F0Bug                         ; run the F0-bug

NoF0Bug:
  call      _PNumInts           ; the system didn't have the bug ..
  PrintMsg  HappyMsg            ; .. so lets print the happy-message ..
  PrintMsg  CRLFMsg             ; .. instead of the error-message

;-----------------------------------------------------------------------------
; Restore invalid opcode interrupt handler
;-----------------------------------------------------------------------------
Exit:
  push      es                       ; save
  mov       ax,seg INTSEG
  mov       es,ax
  mov       ax,word ptr OrigINT06[0] ; get pointer to our INT06 handler
  mov       dx,word ptr OrigINT06[2] ; get our code segment
  xchg      ax,word ptr es:INT06     ; swap 'em
  xchg      dx,word ptr es:INT06[2]  ; swap vector
  pop       es                       ; restore original segment

;-----------------------------------------------------------------------------
; Terminate and return to DOS.
;-----------------------------------------------------------------------------
  iret                               ; return to DOS
OPCODE endp

;-----------------------------------------------------------------------------
; Print the number of times the INT06-handler has been called.
;-----------------------------------------------------------------------------
_PNumInts PROC NEAR
  PrintMsg  IntMsg
  mov       ax,NumInts
  call      _dpt
  PrintMsg  IntMsg2
  ret
_PNumInts ENDP

;-----------------------------------------------------------------------------
; Print the decimal number in AX.
;-----------------------------------------------------------------------------
_dpt PROC NEAR        ; Entry-point for printing in decimal
  mov       cx,10
dploop:               ; Entry-point for printing in CX-notation
  xor       dx,dx
  div       cx
  push      dx
  cmp       ax,0
  je        undo
  call      dploop
undo:                     
  pop       dx
pdig:                 ; Entry-point for printing a small digit in DL
  add       dl,30h
  cmp       dl,39h
  jle       pch
  add       al,7
pch:                  ; Entry-point for printing a single character
  mov       ah,2
  int       21h
  ret              
_dpt ENDP             

;-----------------------------------------------------------------------------
; This is a real down-and-dirty invalid opcode exception handler.  All this
; handler does, is take the value in DX and use it as the return address.
;-----------------------------------------------------------------------------
; Input:   DX = Return address
; Output:  None
;-----------------------------------------------------------------------------
OurINT6 proc far
  inc       NumInts   ; inc the no. of times the handler has been called
  pop       ax        ; get IP from stack
  mov       ax,dx     ; point to return address
  push      ax        ; save it
  iret                ; go split
OurINT6 endp

_TEXT	ENDS

STACKSEG segment para public STACK
;-----------------------------------------------------------------------------
; Stack segment
;-----------------------------------------------------------------------------
  StackPtr	db	40h dup (?)
STACKSEG	ends

end OPCODE
Output

On a buggy CPU:

This program tests your CPU for the Pentium-F0 bug.
NOTE: This program will crash ANY Pentium Classic/MMX system.

Press SPACE to continue, or any other key to quit...

[Int 6 called 0 time(s)] - Testing the LoadAll-instruction
[Int 6 called 1 time(s)] - Now testing for the F0-bug:

FAILED: Your CPU has the bug :(  (PRESS RESET)
On a healthy CPU:
This program tests your CPU for the Pentium-F0 bug.
NOTE: This program will crash ANY Pentium Classic/MMX system.

Press SPACE to continue, or any other key to quit...

[Int 6 called 0 time(s)] - Testing the LoadAll-instruction
[Int 6 called 1 time(s)] - Now testing for the F0-bug:

[Int 6 called 2 time(s)] - PASSED: You CPU doesn't have this bug :)
The EXE-file.
You may also download the compiled .EXE-file: F0BUG.EXE

List of Other Well-known Pentium-bugs.

- The FDIV-bug    (Pentium 60-90 only)
- The DAN0411-bug (Pentium Pro and Pentium II only)
- The F0-bug      (All Intel Pentiums (Classic and MMX))
For a more complete list of bugs in the Intel 80x86 family, see the file 86BUGS.LST included in Ralf Browns Interrupt-list.

Links.
www.x86.org

The Pentium Pro / Pentium II bug - page.

Ralf Browns Interruptlist

www.news.com (best news-site around!)

Thanks To.
Thanks to all who have commented and discussed the bug in the Danish Fido-net echoes: PASCAL_R23.PUB and HARDSOFT_R23.PUB.

I will not mention any names, since I probably would forget you. Ingen nævnt - ingen glemt.