3571e53040
patches for easier mirroring, to eliminate a special copy, to make www.freebsd.org/security a full copy of security.freebsd.org and be eventually be the same. For now files are just sitting there. The symlinks are missing. Discussed on: www (repository location) Discussed with: simon (so)
234 lines
7.4 KiB
Text
234 lines
7.4 KiB
Text
-----BEGIN PGP SIGNED MESSAGE-----
|
|
|
|
=============================================================================
|
|
FreeBSD-SA-97:06 Security Advisory
|
|
FreeBSD, Inc.
|
|
|
|
Topic: Pentium processors have flaw allowing unpriviledged crashes
|
|
|
|
Category: core
|
|
Module: kern
|
|
Announced: 1997-12-09
|
|
Affects: FreeBSD 2.1.*, FreeBSD 2.2.*,
|
|
FreeBSD-stable and FreeBSD-current
|
|
Corrected: FreeBSD-current as of 1997-12-04
|
|
FreeBSD-stable as of 1997-12-04
|
|
FreeBSD only: no
|
|
|
|
Patches: ftp://freebsd.org/pub/CERT/patches/SA-97:06/
|
|
|
|
=============================================================================
|
|
|
|
I. Background
|
|
|
|
Intel processors have instruction combiniations that, when
|
|
executed, produce illegal instruction traps. This is a normal
|
|
part of every cpu manufactured and is how new instructions are
|
|
generally emulated on older hardware.
|
|
|
|
II. Problem Description
|
|
|
|
A specific sequence of instructions, starting with the byte codes
|
|
F0 0F (hex) cause Pentium processors to lock up. This lockup
|
|
wedges the entire system, requiring a hard reset to correct.
|
|
Systems that allow users to run arbitrary code are vulnerable to
|
|
this attack.
|
|
|
|
III. Impact
|
|
|
|
An unpriviledged user can crash your system.
|
|
|
|
IV. Workaround
|
|
|
|
None is available.
|
|
|
|
V. Solution
|
|
|
|
The following patch corrects the problem for FreeBSD-current
|
|
systems before 1997-12-04, for FreeBSD 2.2-stable before
|
|
1997-12-04 and for FreeBSD 2.2.5.
|
|
|
|
We urge users of FreeBSD 2.1.* to upgrade to the more stable and
|
|
more powerfull FreeBSD 2.2.5 release.
|
|
|
|
|
|
Index: identcpu.c
|
|
===================================================================
|
|
RCS file: /home/cvsup/freebsd/CVS/src/sys/i386/i386/identcpu.c,v
|
|
retrieving revision 1.33
|
|
retrieving revision 1.35
|
|
diff -u -r1.33 -r1.35
|
|
--- identcpu.c 1997/11/07 08:52:27 1.33
|
|
+++ identcpu.c 1997/12/04 14:35:38 1.35
|
|
@@ -107,6 +107,10 @@
|
|
);
|
|
}
|
|
|
|
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
|
+int has_f00f_bug = 0;
|
|
+#endif
|
|
+
|
|
void
|
|
printcpuinfo(void)
|
|
{
|
|
@@ -136,6 +140,14 @@
|
|
break;
|
|
case 0x500:
|
|
strcat(cpu_model, "Pentium"); /* nb no space */
|
|
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
|
+ /*
|
|
+ * XXX - If/when Intel fixes the bug, this
|
|
+ * should also check the version of the
|
|
+ * CPU, not just that it's a Pentium.
|
|
+ */
|
|
+ has_f00f_bug = 1;
|
|
+#endif
|
|
break;
|
|
case 0x600:
|
|
strcat(cpu_model, "Pentium Pro");
|
|
Index: machdep.c
|
|
===================================================================
|
|
RCS file: /home/cvsup/freebsd/CVS/src/sys/i386/i386/machdep.c,v
|
|
retrieving revision 1.274
|
|
retrieving revision 1.278
|
|
diff -u -r1.274 -r1.278
|
|
--- machdep.c 1997/11/24 18:35:11 1.274
|
|
+++ machdep.c 1997/12/04 21:21:24 1.278
|
|
@@ -866,6 +867,11 @@
|
|
#endif /* VM86 */
|
|
#endif
|
|
|
|
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
|
+struct gate_descriptor *t_idt;
|
|
+extern int has_f00f_bug;
|
|
+#endif
|
|
+
|
|
static struct i386tss dblfault_tss;
|
|
static char dblfault_stack[PAGE_SIZE];
|
|
|
|
@@ -1533,6 +1539,40 @@
|
|
proc0.p_addr->u_pcb.pcb_mpnest = 1;
|
|
proc0.p_addr->u_pcb.pcb_ext = 0;
|
|
}
|
|
+
|
|
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
|
+void f00f_hack(void);
|
|
+SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL);
|
|
+
|
|
+void
|
|
+f00f_hack(void) {
|
|
+ struct region_descriptor r_idt;
|
|
+ unsigned char *tmp;
|
|
+ int i;
|
|
+
|
|
+ if (!has_f00f_bug)
|
|
+ return;
|
|
+
|
|
+ printf("Intel Pentium F00F detected, installing workaround\n");
|
|
+
|
|
+ r_idt.rd_limit = sizeof(idt) - 1;
|
|
+
|
|
+ tmp = kmem_alloc(kernel_map, PAGE_SIZE * 2);
|
|
+ if (tmp == 0)
|
|
+ panic("kmem_alloc returned 0");
|
|
+ if (((unsigned int)tmp & (PAGE_SIZE-1)) != 0)
|
|
+ panic("kmem_alloc returned non-page-aligned memory");
|
|
+ /* Put the first seven entries in the lower page */
|
|
+ t_idt = (struct gate_descriptor*)(tmp + PAGE_SIZE - (7*8));
|
|
+ bcopy(idt, t_idt, sizeof(idt));
|
|
+ r_idt.rd_base = (int)t_idt;
|
|
+ lidt(&r_idt);
|
|
+ if (vm_map_protect(kernel_map, tmp, tmp + PAGE_SIZE,
|
|
+ VM_PROT_READ, FALSE) != KERN_SUCCESS)
|
|
+ panic("vm_map_protect failed");
|
|
+ return;
|
|
+}
|
|
+#endif /* defined(I586_CPU) && !NO_F00F_HACK */
|
|
|
|
int
|
|
ptrace_set_pc(p, addr)
|
|
Index: trap.c
|
|
===================================================================
|
|
RCS file: /home/cvsup/freebsd/CVS/src/sys/i386/i386/trap.c,v
|
|
retrieving revision 1.115
|
|
retrieving revision 1.118
|
|
diff -u -r1.115 -r1.118
|
|
--- trap.c 1997/11/24 13:25:37 1.115
|
|
+++ trap.c 1997/12/04 21:21:26 1.118
|
|
@@ -142,6 +143,11 @@
|
|
static void userret __P((struct proc *p, struct trapframe *frame,
|
|
u_quad_t oticks));
|
|
|
|
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
|
+extern struct gate_descriptor *t_idt;
|
|
+extern int has_f00f_bug;
|
|
+#endif
|
|
+
|
|
static inline void
|
|
userret(p, frame, oticks)
|
|
struct proc *p;
|
|
@@ -211,6 +217,9 @@
|
|
u_long eva;
|
|
#endif
|
|
|
|
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
|
+restart:
|
|
+#endif
|
|
type = frame.tf_trapno;
|
|
code = frame.tf_err;
|
|
|
|
@@ -276,6 +285,10 @@
|
|
i = trap_pfault(&frame, TRUE);
|
|
if (i == -1)
|
|
return;
|
|
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
|
+ if (i == -2)
|
|
+ goto restart;
|
|
+#endif
|
|
if (i == 0)
|
|
goto out;
|
|
|
|
@@ -642,7 +655,18 @@
|
|
if (va >= KERNBASE) {
|
|
/*
|
|
* Don't allow user-mode faults in kernel address space.
|
|
+ * An exception: if the faulting address is the invalid
|
|
+ * instruction entry in the IDT, then the Intel Pentium
|
|
+ * F00F bug workaround was triggered, and we need to
|
|
+ * treat it is as an illegal instruction, and not a page
|
|
+ * fault.
|
|
*/
|
|
+#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
|
+ if ((eva == (unsigned int)&t_idt[6]) && has_f00f_bug) {
|
|
+ frame->tf_trapno = T_PRIVINFLT;
|
|
+ return -2;
|
|
+ }
|
|
+#endif
|
|
if (usermode)
|
|
goto nogo;
|
|
|
|
|
|
=============================================================================
|
|
FreeBSD, Inc.
|
|
|
|
Web Site: http://www.freebsd.org/
|
|
Confidential contacts: security-officer@freebsd.org
|
|
PGP Key: ftp://freebsd.org/pub/CERT/public_key.asc
|
|
Security notifications: security-notifications@freebsd.org
|
|
Security public discussion: security@freebsd.org
|
|
|
|
Notice: Any patches in this document may not apply cleanly due to
|
|
modifications caused by digital signature or mailer software.
|
|
Please reference the URL listed at the top of this document
|
|
for original copies of all patches if necessary.
|
|
=============================================================================
|
|
|
|
-----BEGIN PGP SIGNATURE-----
|
|
Version: 2.6.2
|
|
|
|
iQCVAwUBNI2g9VUuHi5z0oilAQGFnAP/R4bArrM7+NZKbrJEK+9UpNYBPhsakAF6
|
|
4/U1wJJdbBJPl5j4udZki8ZUEPJvM2mSnrs9UevQMYGSoirl92h/0SEgVgjIfhcJ
|
|
tcyY97Js6biHAZzib4i/TKoN47wBNjgRLF6SfafuIxfVQYk6RMFB5EUdYBdseVz/
|
|
5RgYqQz4m/k=
|
|
=xvTs
|
|
-----END PGP SIGNATURE-----
|