From hunt@mph124.rh.psu.edu  Fri Nov 21 13:30:19 1997
Received: from mph124.rh.psu.edu (hunt@MPH124.rh.psu.edu [128.118.126.83])
          by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id NAA14304
          for <FreeBSD-gnats-submit@freebsd.org>; Fri, 21 Nov 1997 13:30:12 -0800 (PST)
          (envelope-from hunt@mph124.rh.psu.edu)
Received: (from hunt@localhost)
	by mph124.rh.psu.edu (8.8.7/8.8.7) id QAA00709;
	Fri, 21 Nov 1997 16:30:09 -0500 (EST)
	(envelope-from hunt)
Message-Id: <199711212130.QAA00709@mph124.rh.psu.edu>
Date: Fri, 21 Nov 1997 16:30:09 -0500 (EST)
From: mph@pobox.com
To: FreeBSD-gnats-submit@freebsd.org
Subject: NO_LOCK 6x86 fix is wrong
X-Send-Pr-Version: 3.2

>Number:         5121
>Category:       i386
>Synopsis:       NO_LOCK 6x86 fix is wrong
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Nov 21 13:40:00 PST 1997
>Closed-Date:    Fri Nov 21 14:38:10 PST 1997
>Last-Modified:  Fri Nov 21 14:40:04 PST 1997
>Originator:     Matthew Hunt
>Release:        FreeBSD 2.2.5-STABLE i386
>Organization:
none
>Environment:

Cyrix 6x86

/usr/src/sys/i386/i386/initcpu.c:
     $Id: initcpu.c,v 1.5.2.4 1997/10/17 08:29:01 kato Exp $

>Description:

As discussed in freebsd-questions, the Cyrix 6x86 has a lockup
bug that should be cured with the CPU_CYRIX_NO_LOCK kernel option.

For more info, see http://www.tux.org/~balsa/linux/cyrix/p11.html.

initcpu.c reads:

        /* Initialize CCR0. */
        write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR0_NC1);

        /* Initialize CCR1. */
#ifdef CPU_CYRIX_NO_LOCK
        write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR1_NO_LOCK);
#else
#ifdef FAILSAFE
        write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) & ~CCR1_NO_LOCK);
#endif
#endif

When the comments and the code disagree, it's a good sign that something
is wrong.  In fact, the code is modifying the wrong register, CCR0
instead of CCR1.  With initcpu.c unchanged, and CPU_CYRIX_NO_LOCK
defined, the machine is still susceptible to the attack.

>How-To-Repeat:

Do not modify initcpu.c.  Compile with the CPU_CYRIX_NO_LOCK option.
Run the exploit:

static unsigned char c[4] = {0x36, 0x78, 0x38, 0x36};

main() {
	asm ("movl $_c, %ebx\n\t"
	"again: xchgl (%ebx), %eax\n\t"
	"movl %eax, %edx\n\t"
	"jmp again\n\t");
}

>Fix:

Apply the following patch to initcpu.c; with this patch, and
CPU_CYRIX_NO_LOCK defined, the attack just runs forever, and can
be stopped with control-C.


--- /usr/src/sys/i386/i386/initcpu.c	Fri Oct 17 04:29:01 1997
+++ initcpu.c	Fri Nov 21 16:18:20 1997
@@ -306,10 +306,10 @@
 
 	/* Initialize CCR1. */
 #ifdef CPU_CYRIX_NO_LOCK
-	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) | CCR1_NO_LOCK);
+	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) | CCR1_NO_LOCK);
 #else
 #ifdef FAILSAFE
-	write_cyrix_reg(CCR0, read_cyrix_reg(CCR0) & ~CCR1_NO_LOCK);
+	write_cyrix_reg(CCR1, read_cyrix_reg(CCR1) & ~CCR1_NO_LOCK);
 #endif
 #endif
 
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: jlemon 
State-Changed-When: Fri Nov 21 14:38:10 PST 1997 
State-Changed-Why:  

Corrected in initcpu.c:1.5.2.5, initcpu.c:1.10 
>Unformatted:
