Mon Jul 20 16:37:35 2020 UTC ()
Revert 1.67 "Restore the lwp's fpu state, not zeros, and leave with fpu enabled."

This didn't actually avoid double-restore, and it doesn't solve the
problem anyway, and made it harder to detect in-kernel fpu abuse.


(riastradh)
diff -r1.68 -r1.69 src/sys/arch/x86/x86/fpu.c

cvs diff -r1.68 -r1.69 src/sys/arch/x86/x86/fpu.c (expand / switch to unified diff)

--- src/sys/arch/x86/x86/fpu.c 2020/07/13 16:51:51 1.68
+++ src/sys/arch/x86/x86/fpu.c 2020/07/20 16:37:34 1.69
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: fpu.c,v 1.68 2020/07/13 16:51:51 riastradh Exp $ */ 1/* $NetBSD: fpu.c,v 1.69 2020/07/20 16:37:34 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008, 2019 The NetBSD Foundation, Inc. All 4 * Copyright (c) 2008, 2019 The NetBSD Foundation, Inc. All
5 * rights reserved. 5 * rights reserved.
6 * 6 *
7 * This code is derived from software developed for The NetBSD Foundation 7 * This code is derived from software developed for The NetBSD Foundation
8 * by Andrew Doran and Maxime Villard. 8 * by Andrew Doran and Maxime Villard.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -86,27 +86,27 @@ @@ -86,27 +86,27 @@
86 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 86 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
87 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 87 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
88 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 88 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
89 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 89 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
90 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 90 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
91 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 91 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
92 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 92 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
93 * SUCH DAMAGE. 93 * SUCH DAMAGE.
94 * 94 *
95 * @(#)npx.c 7.2 (Berkeley) 5/12/91 95 * @(#)npx.c 7.2 (Berkeley) 5/12/91
96 */ 96 */
97 97
98#include <sys/cdefs.h> 98#include <sys/cdefs.h>
99__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.68 2020/07/13 16:51:51 riastradh Exp $"); 99__KERNEL_RCSID(0, "$NetBSD: fpu.c,v 1.69 2020/07/20 16:37:34 riastradh Exp $");
100 100
101#include "opt_multiprocessor.h" 101#include "opt_multiprocessor.h"
102 102
103#include <sys/param.h> 103#include <sys/param.h>
104#include <sys/systm.h> 104#include <sys/systm.h>
105#include <sys/conf.h> 105#include <sys/conf.h>
106#include <sys/cpu.h> 106#include <sys/cpu.h>
107#include <sys/file.h> 107#include <sys/file.h>
108#include <sys/proc.h> 108#include <sys/proc.h>
109#include <sys/kernel.h> 109#include <sys/kernel.h>
110#include <sys/sysctl.h> 110#include <sys/sysctl.h>
111#include <sys/xcall.h> 111#include <sys/xcall.h>
112 112
@@ -411,48 +411,44 @@ fpu_kern_enter(void) @@ -411,48 +411,44 @@ fpu_kern_enter(void)
411 */ 411 */
412 clts(); 412 clts();
413} 413}
414 414
415/* 415/*
416 * fpu_kern_leave() 416 * fpu_kern_leave()
417 * 417 *
418 * End using the FPU after fpu_kern_enter(). 418 * End using the FPU after fpu_kern_enter().
419 */ 419 */
420void 420void
421fpu_kern_leave(void) 421fpu_kern_leave(void)
422{ 422{
423 static const union savefpu zero_fpu __aligned(64); 423 static const union savefpu zero_fpu __aligned(64);
424 const union savefpu *savefpu; 
425 struct lwp *l = curlwp; 
426 struct pcb *pcb; 
427 struct cpu_info *ci = curcpu(); 424 struct cpu_info *ci = curcpu();
428 int s; 425 int s;
429 426
430 KASSERT(ci->ci_ilevel == IPL_VM); 427 KASSERT(ci->ci_ilevel == IPL_VM);
431 KASSERT(ci->ci_kfpu_spl != -1); 428 KASSERT(ci->ci_kfpu_spl != -1);
432 429
433 /* 430 /*
434 * Restore the FPU state immediately to avoid leaking any 431 * Zero the fpu registers; otherwise we might leak secrets
435 * kernel secrets, or zero it if this is a kthread. 432 * through Spectre-class attacks to userland, even if there are
 433 * no bugs in fpu state management.
436 */ 434 */
437 if ((l->l_pflag & LP_INTR) && (l->l_switchto != NULL)) 435 fpu_area_restore(&zero_fpu, x86_xsave_features);
438 l = l->l_switchto; 436
439 if (l->l_flag & LW_SYSTEM) { 437 /*
440 savefpu = &zero_fpu; 438 * Set CR0_TS again so that the kernel can't accidentally use
441 } else { 439 * the FPU.
442 pcb = lwp_getpcb(l); 440 */
443 savefpu = &pcb->pcb_savefpu; 441 stts();
444 } 
445 fpu_area_restore(savefpu, x86_xsave_features); 
446 442
447 s = ci->ci_kfpu_spl; 443 s = ci->ci_kfpu_spl;
448 ci->ci_kfpu_spl = -1; 444 ci->ci_kfpu_spl = -1;
449 splx(s); 445 splx(s);
450} 446}
451 447
452/* -------------------------------------------------------------------------- */ 448/* -------------------------------------------------------------------------- */
453 449
454/* 450/*
455 * The following table is used to ensure that the FPE_... value 451 * The following table is used to ensure that the FPE_... value
456 * that is passed as a trapcode to the signal handler of the user 452 * that is passed as a trapcode to the signal handler of the user
457 * process does not have more than one bit set. 453 * process does not have more than one bit set.
458 * 454 *