Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Nov 1997 16:30:09 -0500 (EST)
From:      mph@pobox.com
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   i386/5121: NO_LOCK 6x86 fix is wrong
Message-ID:  <199711212130.QAA00709@mph124.rh.psu.edu>
Resent-Message-ID: <199711212140.NAA15449@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         5121
>Category:       i386
>Synopsis:       NO_LOCK 6x86 fix is wrong
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Nov 21 13:40:00 PST 1997
>Last-Modified:
>Originator:     Matthew Hunt
>Organization:
none
>Release:        FreeBSD 2.2.5-STABLE i386
>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
 
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711212130.QAA00709>