Module Name: src Committed By: snj Date: Mon Feb 19 20:54:38 UTC 2018
Modified Files: src/sys/arch/amd64/amd64 [netbsd-6]: machdep.c src/sys/arch/amd64/include [netbsd-6]: segments.h src/sys/arch/i386/i386 [netbsd-6]: machdep.c src/sys/arch/i386/include [netbsd-6]: segments.h src/sys/arch/x86/x86 [netbsd-6]: vm_machdep.c Log Message: Pull up following revision(s) (requested by maxv in ticket #1517): sys/arch/amd64/amd64/machdep.c: 1.280 via patch sys/arch/amd64/include/segments.h: 1.34 via patch sys/arch/i386/i386/machdep.c: 1.800 sys/arch/i386/include/segments.h: 1.64 sys/arch/x86/x86/vm_machdep.c: 1.30 Fix a huge privilege separation vulnerability in Xen-amd64. On amd64 the kernel runs in ring3, like userland, and therefore SEL_KPL equals SEL_UPL. While Xen can make a distinction between usermode and kernelmode in %cs, it can't when it comes to iopl. Since we set SEL_KPL in iopl, Xen sees SEL_UPL, and allows (unprivileged) userland processes to read and write to the CPU ports. It is easy, then, to completely escalate privileges; by reprogramming the PIC, by reading the ATA disks, by intercepting the keyboard interrupts (keylogger), etc. Declare IOPL_KPL, set to 1 on Xen-amd64, which allows the kernel to use the ports but not userland. I didn't test this change on i386, but it seems fine enough. To generate a diff of this commit: cvs rdiff -u -r1.175.2.9 -r1.175.2.10 src/sys/arch/amd64/amd64/machdep.c cvs rdiff -u -r1.22 -r1.22.10.1 src/sys/arch/amd64/include/segments.h cvs rdiff -u -r1.717.2.8 -r1.717.2.9 src/sys/arch/i386/i386/machdep.c cvs rdiff -u -r1.54 -r1.54.10.1 src/sys/arch/i386/include/segments.h cvs rdiff -u -r1.14 -r1.14.2.1 src/sys/arch/x86/x86/vm_machdep.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/amd64/amd64/machdep.c diff -u src/sys/arch/amd64/amd64/machdep.c:1.175.2.9 src/sys/arch/amd64/amd64/machdep.c:1.175.2.10 --- src/sys/arch/amd64/amd64/machdep.c:1.175.2.9 Tue Aug 8 12:00:35 2017 +++ src/sys/arch/amd64/amd64/machdep.c Mon Feb 19 20:54:37 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.175.2.9 2017/08/08 12:00:35 martin Exp $ */ +/* $NetBSD: machdep.c,v 1.175.2.10 2018/02/19 20:54:37 snj Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2006, 2007, 2008, 2011 @@ -111,7 +111,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.175.2.9 2017/08/08 12:00:35 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.175.2.10 2018/02/19 20:54:37 snj Exp $"); /* #define XENDEBUG_LOW */ @@ -477,7 +477,7 @@ x86_64_proc0_tss_ldt_init(void) pcb->pcb_fs = 0; pcb->pcb_gs = 0; pcb->pcb_rsp0 = (uvm_lwp_getuarea(l) + KSTACK_SIZE - 16) & ~0xf; - pcb->pcb_iopl = SEL_KPL; + pcb->pcb_iopl = IOPL_KPL; pmap_kernel()->pm_ldt_sel = GSYSSEL(GLDT_SEL, SEL_KPL); pcb->pcb_cr0 = rcr0() & ~CR0_TS; Index: src/sys/arch/amd64/include/segments.h diff -u src/sys/arch/amd64/include/segments.h:1.22 src/sys/arch/amd64/include/segments.h:1.22.10.1 --- src/sys/arch/amd64/include/segments.h:1.22 Mon Feb 7 03:54:45 2011 +++ src/sys/arch/amd64/include/segments.h Mon Feb 19 20:54:37 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: segments.h,v 1.22 2011/02/07 03:54:45 chs Exp $ */ +/* $NetBSD: segments.h,v 1.22.10.1 2018/02/19 20:54:37 snj Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -107,6 +107,12 @@ #define ISLDT(s) ((s) & SEL_LDT) /* is it local or global */ #define SEL_LDT 4 /* local descriptor table */ +#ifdef XEN +#define IOPL_KPL 1 +#else +#define IOPL_KPL SEL_KPL +#endif + /* Dynamically allocated TSSs and LDTs start (byte offset) */ #define SYSSEL_START (NGDT_MEM << 3) #define DYNSEL_START (SYSSEL_START + (NGDT_SYS << 4)) Index: src/sys/arch/i386/i386/machdep.c diff -u src/sys/arch/i386/i386/machdep.c:1.717.2.8 src/sys/arch/i386/i386/machdep.c:1.717.2.9 --- src/sys/arch/i386/i386/machdep.c:1.717.2.8 Tue Aug 8 12:00:35 2017 +++ src/sys/arch/i386/i386/machdep.c Mon Feb 19 20:54:38 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.717.2.8 2017/08/08 12:00:35 martin Exp $ */ +/* $NetBSD: machdep.c,v 1.717.2.9 2018/02/19 20:54:38 snj Exp $ */ /*- * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009 @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.717.2.8 2017/08/08 12:00:35 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.717.2.9 2018/02/19 20:54:38 snj Exp $"); #include "opt_beep.h" #include "opt_compat_ibcs2.h" @@ -509,7 +509,7 @@ i386_proc0_tss_ldt_init(void) pmap_kernel()->pm_ldt_sel = GSEL(GLDT_SEL, SEL_KPL); pcb->pcb_cr0 = rcr0() & ~CR0_TS; pcb->pcb_esp0 = uvm_lwp_getuarea(l) + KSTACK_SIZE - 16; - pcb->pcb_iopl = SEL_KPL; + pcb->pcb_iopl = IOPL_KPL; l->l_md.md_regs = (struct trapframe *)pcb->pcb_esp0 - 1; memcpy(&pcb->pcb_fsd, &gdt[GUDATA_SEL], sizeof(pcb->pcb_fsd)); memcpy(&pcb->pcb_gsd, &gdt[GUDATA_SEL], sizeof(pcb->pcb_gsd)); Index: src/sys/arch/i386/include/segments.h diff -u src/sys/arch/i386/include/segments.h:1.54 src/sys/arch/i386/include/segments.h:1.54.10.1 --- src/sys/arch/i386/include/segments.h:1.54 Tue Apr 26 15:51:23 2011 +++ src/sys/arch/i386/include/segments.h Mon Feb 19 20:54:38 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: segments.h,v 1.54 2011/04/26 15:51:23 joerg Exp $ */ +/* $NetBSD: segments.h,v 1.54.10.1 2018/02/19 20:54:38 snj Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -104,6 +104,9 @@ #endif /* XEN */ #define ISLDT(s) ((s) & SEL_LDT) /* is it local or global */ #define SEL_LDT 4 /* local descriptor table */ + +#define IOPL_KPL SEL_KPL + #define IDXSEL(s) (((s) >> 3) & 0x1fff) /* index of selector */ #define IDXSELN(s) (((s) >> 3)) /* index of selector */ #define GSEL(s,r) (((s) << 3) | r) /* a global selector */ Index: src/sys/arch/x86/x86/vm_machdep.c diff -u src/sys/arch/x86/x86/vm_machdep.c:1.14 src/sys/arch/x86/x86/vm_machdep.c:1.14.2.1 --- src/sys/arch/x86/x86/vm_machdep.c:1.14 Sat Jan 21 16:48:57 2012 +++ src/sys/arch/x86/x86/vm_machdep.c Mon Feb 19 20:54:38 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: vm_machdep.c,v 1.14 2012/01/21 16:48:57 chs Exp $ */ +/* $NetBSD: vm_machdep.c,v 1.14.2.1 2018/02/19 20:54:38 snj Exp $ */ /*- * Copyright (c) 1982, 1986 The Regents of the University of California. @@ -80,7 +80,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.14 2012/01/21 16:48:57 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.14.2.1 2018/02/19 20:54:38 snj Exp $"); #include "opt_mtrr.h" @@ -165,7 +165,7 @@ cpu_lwp_fork(struct lwp *l1, struct lwp memcpy(pcb2, pcb1, sizeof(struct pcb)); #if defined(XEN) - pcb2->pcb_iopl = SEL_KPL; + pcb2->pcb_iopl = IOPL_KPL; #endif /*