From: mlarkin Date: Sun, 21 Dec 2014 16:27:07 +0000 (+0000) Subject: Prevent writing to the kernel area via the direct map. We do this by padding X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=c7636a68831104520cbf866b4b8d6bf887102168;p=openbsd Prevent writing to the kernel area via the direct map. We do this by padding the end of the kernel area to 2MB, so that the direct map pages can then have the W permission removed (X permission was already removed in a previous diff). This creates a VA hole at the end of bss, so adjust for that since that's where symbols get loaded by the bootloader (for now, map that region RO until the boot loader can be updated to place the symbols at "end" instead of "end of bss"). with help from and ok deraadt@ --- diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S index eeecb1157b1..022cd07ef38 100644 --- a/sys/arch/amd64/amd64/locore.S +++ b/sys/arch/amd64/amd64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.60 2014/11/27 17:35:12 mlarkin Exp $ */ +/* $OpenBSD: locore.S,v 1.61 2014/12/21 16:27:07 mlarkin Exp $ */ /* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */ /* @@ -174,7 +174,7 @@ _C_LABEL(lapic_isr): .globl _C_LABEL(cpu_perf_ebx) .globl _C_LABEL(cpu_perf_edx) .globl _C_LABEL(cpu_apmi_edx) - .globl _C_LABEL(esym),_C_LABEL(boothowto),_C_LABEL(bootdev) + .globl _C_LABEL(ssym),_C_LABEL(esym),_C_LABEL(boothowto),_C_LABEL(bootdev) .globl _C_LABEL(bootinfo), _C_LABEL(bootinfo_size), _C_LABEL(atdevbase) .globl _C_LABEL(proc0paddr),_C_LABEL(PTDpaddr) .globl _C_LABEL(biosbasemem),_C_LABEL(biosextmem) @@ -196,6 +196,7 @@ _C_LABEL(cpuid_level): .long -1 # max. level accepted by 'cpuid' _C_LABEL(cpu_vendor): .space 16 # vendor string returned by `cpuid' # instruction _C_LABEL(cpu_brand_id): .long 0 # brand ID from 'cpuid' instruction +_C_LABEL(ssym): .quad 0 # ptr to start of syms _C_LABEL(esym): .quad 0 # ptr to end of syms _C_LABEL(atdevbase): .quad 0 # location of start of iomem in virtual _C_LABEL(bootapiver): .long 0 # /boot API version @@ -474,14 +475,46 @@ cont: orl $(PG_V|PG_KR), %eax fillkpt_nx - /* Reload %edx for data_start */ - movl $RELOC(__data_start), %edx + /* Map the data and BSS sections RW, NX */ + movl $RELOC(__data_start), %eax + movl $RELOC(__kernel_bss_end),%ecx + addl $PGOFSET, %ecx + andl $~PGOFSET, %ecx + subl %eax, %ecx + shrl $PGSHIFT,%ecx + orl $(PG_V|PG_KW), %eax + fillkpt_nx - /* Map the data, BSS, and bootstrap tables RW, NX */ + /* Map "hole" at end of BSS RO, NX */ + movl $RELOC(__kernel_bss_end), %eax + movl $RELOC(end), %ecx + addl $PGOFSET, %ecx + andl $~PGOFSET, %ecx + cmpl %eax, %ecx + je map_syms + subl %eax, %ecx + shrl $PGSHIFT, %ecx + orl $(PG_V|PG_KR), %eax + fillkpt_nx + +map_syms: + /* Map symbol space RO, NX */ + movl $RELOC(end), %eax + movl %esi, %ecx + addl $PGOFSET, %ecx + andl $~PGOFSET, %ecx + cmpl %eax, %ecx + je map_tables + subl %eax, %ecx + shrl $PGSHIFT, %ecx + orl $(PG_V|PG_KR), %eax + fillkpt_nx + +map_tables: + /* Map the bootstrap tables RW, NX */ + movl %esi, %edx leal (PG_V|PG_KW)(%edx),%eax movl $TABLESIZE,%ecx - addl %esi,%ecx /* %ecx = end + TABLESIZE */ - subl %edx,%ecx /* %ecx = %ecx - data_start */ shrl $PGSHIFT,%ecx fillkpt_nx @@ -539,13 +572,22 @@ cont: /* * Map the first 4 GB with the direct map. We'll map the rest * in pmap_bootstrap. But we always need the first 4GB during - * bootstrap. The direct map is mapped RW, NX. + * bootstrap. The direct map is mapped RW, NX. We also change + * the permissions on the 2MB pages corresponding to the kernel + * PAs to RO to prevent someone writing to the kernel area + * via the direct map. */ leal (PROC0_DMP2_OFF)(%esi), %ebx xorl %eax, %eax - orl $(PG_V|PG_KW|PG_PS|PG_G), %eax movl $(NDML2_ENTRIES * NPDPG), %ecx -1: movl %eax, (%ebx) +1: orl $(PG_V|PG_KW|PG_PS|PG_G), %eax + cmpl $__kernel_base_phys, %eax + jl store_pte + cmpl $__kernel_end_phys, %eax + jg store_pte + andl $(~PG_KW), %eax +store_pte: + movl %eax, (%ebx) pushl %ebp movl RELOC((pg_nx + 4)), %ebp movl %ebp, 4(%ebx) @@ -681,6 +723,9 @@ longmode_hi: addq %rsi,%rdx movq %rdx,_C_LABEL(atdevbase)(%rip) + /* Record start of symbols */ + movq $__kernel_bss_end, _C_LABEL(ssym)(%rip) + /* Set up bootstrap stack. */ leaq (PROC0_STK_OFF)(%rsi),%rax addq %r8,%rax diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index d1a6fdd4276..53402f706fb 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.203 2014/12/18 05:33:48 mlarkin Exp $ */ +/* $OpenBSD: machdep.c,v 1.204 2014/12/21 16:27:07 mlarkin Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -177,8 +177,6 @@ paddr_t dumpmem_paddr; vaddr_t dumpmem_vaddr; psize_t dumpmem_sz; - -char *ssym = NULL; vaddr_t kern_end; vaddr_t msgbuf_vaddr; diff --git a/sys/arch/amd64/conf/ld.script b/sys/arch/amd64/conf/ld.script index 4dc06ff4c0e..15178e33788 100644 --- a/sys/arch/amd64/conf/ld.script +++ b/sys/arch/amd64/conf/ld.script @@ -1,4 +1,4 @@ -/* $OpenBSD: ld.script,v 1.1 2014/11/18 01:11:13 deraadt Exp $ */ +/* $OpenBSD: ld.script,v 1.2 2014/12/21 16:27:07 mlarkin Exp $ */ /* * Copyright (c) 2009 Tobias Weingartner @@ -104,16 +104,16 @@ SECTIONS __bss_load = LOADADDR(.bss); *(.bss .bss.*) *(COMMON) - /* Align here to ensure that the .bss section occupies space - * up to _end. Align after .bss to ensure correct alignment - * even if the .bss section disappears because there are no - * input sections. + /* Align after .bss to ensure correct alignment even if the + * .bss section disappears because there are no input sections. */ - . = ALIGN(64 / 8); + . = ALIGN(0x1000); } :bss - . = ALIGN(64 / 8); + __kernel_bss_end = .; + . = ALIGN(0x200000); _end = .; PROVIDE (end = .); + __kernel_end_phys = . & 0x7fffffff; /* XXX - hack alert, since we are not C++, nuke these */ /DISCARD/ : diff --git a/sys/ddb/db_sym.c b/sys/ddb/db_sym.c index 934fe22dce5..5c209778f85 100644 --- a/sys/ddb/db_sym.c +++ b/sys/ddb/db_sym.c @@ -1,4 +1,4 @@ -/* $OpenBSD: db_sym.c,v 1.35 2014/09/14 14:17:24 jsg Exp $ */ +/* $OpenBSD: db_sym.c,v 1.36 2014/12/21 16:27:08 mlarkin Exp $ */ /* $NetBSD: db_sym.c,v 1.24 2000/08/11 22:50:47 tv Exp $ */ /* @@ -121,13 +121,13 @@ ddb_init(void) const db_symformat_t **symf; const char *name = "bsd"; extern char *esym; -#if defined(__sparc64__) || defined(__mips__) +#if defined(__sparc64__) || defined(__mips__) || defined(__amd64__) extern char *ssym; #endif char *xssym, *xesym; xesym = esym; -#if defined(__sparc64__) || defined(__mips__) +#if defined(__sparc64__) || defined(__mips__) || defined(__amd64__) xssym = ssym; #else xssym = (char *)&end;