Split early startup code out of locore.S into locore0.S. Adjust link
authorderaadt <deraadt@openbsd.org>
Mon, 5 Jun 2017 17:49:05 +0000 (17:49 +0000)
committerderaadt <deraadt@openbsd.org>
Mon, 5 Jun 2017 17:49:05 +0000 (17:49 +0000)
run so that this locore0.o is always at the start of the executable.
But randomize the link order of all other .o files in the kernel, so
that their exec/rodata/data/bss segments land all over the place.

Late during kernel boot, smash the startup code with traps so that
it does not point to the other randomly placed code.  It has be smashed,
because alpha (insecurely in my view) runs in the KSEG0 space.

As a result, the internal layout of every newly build bsd kernel is
different from past kernels.  Internal relative offsets are not known
to an outside attacker.  The only known offsets are in the startup code,
which is gone.

Ramdisk kernels cannot be compiled like this, because they are gzip'd.
When the internal pointer references change, the compression dictionary
bloats and results in poorer compression.

sys/arch/alpha/alpha/autoconf.c
sys/arch/alpha/alpha/locore.s
sys/arch/alpha/alpha/locore0.S [new file with mode: 0644]
sys/arch/alpha/conf/Makefile.alpha
sys/arch/alpha/conf/files.alpha
sys/arch/alpha/include/param.h

index e24b03c..300f7b9 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: autoconf.c,v 1.36 2016/06/08 17:24:44 tedu Exp $      */
+/*     $OpenBSD: autoconf.c,v 1.37 2017/06/05 17:49:05 deraadt Exp $   */
 /*     $NetBSD: autoconf.c,v 1.16 1996/11/13 21:13:04 cgd Exp $        */
 
 /*
@@ -67,6 +67,17 @@ char                 boot_dev[128];
 void   parse_prom_bootdev(void);
 int    atoi(char *);
 
+void
+unmap_startup(void)
+{
+       extern uint32_t kernel_text[], endboot[];
+       uint32_t *word = kernel_text;
+
+       /* Cannot unmap KSEG0; smash with 0x00000000 (call_pall PAL_halt) */
+       while (word < endboot)
+               *word++ = 0x00000000;
+}
+
 /*
  * cpu_configure:
  * called at boot time, configure all devices on system
@@ -77,6 +88,8 @@ cpu_configure()
        parse_prom_bootdev();
        softintr_init();
 
+       unmap_startup();
+
        /*
         * Disable interrupts during autoconfiguration.  splhigh() won't
         * work, because it simply _raises_ the IPL, so if machine checks
index a55cec3..32fc226 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: locore.s,v 1.46 2017/05/27 14:33:39 kettenis Exp $ */
+/* $OpenBSD: locore.s,v 1.47 2017/06/05 17:49:05 deraadt Exp $ */
 /* $NetBSD: locore.s,v 1.94 2001/04/26 03:10:44 ross Exp $ */
 
 /*-
@@ -132,78 +132,6 @@ IMPORT(cpu_info_primary, CPU_INFO_SIZEOF)
        bne     \reg, \dst
        .endm
 
-/*
- * This is for kvm_mkdb, and should be the address of the beginning
- * of the kernel text segment (not necessarily the same as kernbase).
- */
-       EXPORT(kernel_text)
-.loc   1 __LINE__
-kernel_text:
-
-/*
- * bootstack: a temporary stack, for booting.
- *
- * Extends from 'start' down.
- */
-bootstack:
-
-/*
- * __start: Kernel start.
- *
- * Arguments:
- *     a0 is the first free page frame number (PFN) (no longer used)
- *     a1 is the page table base register (PTBR)
- *     a2 is the bootinfo magic number
- *     a3 is the pointer to the bootinfo structure
- *
- * All arguments are passed to alpha_init().
- */
-NESTED_NOPROFILE(__start,1,0,ra,0,0)
-       br      pv,Lstart1
-Lstart1: LDGP(pv)
-
-       /* Switch to the boot stack. */
-       lda     sp,bootstack
-
-       /* Load KGP with current GP. */
-       or      gp,zero,a0
-       call_pal PAL_OSF1_wrkgp         /* clobbers a0, t0, t8-t11 */
-
-       /*
-        * Call alpha_init() to do pre-main initialization.
-        * alpha_init() gets the arguments we were called with,
-        * which are already in a0 (destroyed), a1, a2, a3 and a4.
-        */
-       CALL(alpha_init)
-
-       /* Set up the virtual page table pointer. */
-       ldiq    a0, VPTBASE
-       call_pal PAL_OSF1_wrvptptr      /* clobbers a0, t0, t8-t11 */
-
-       /*
-        * Switch to proc0's PCB.
-        */
-       lda     a0, proc0
-       ldq     a0, P_MD_PCBPADDR(a0)           /* phys addr of PCB */
-       SWITCH_CONTEXT
-
-       /*
-        * We've switched to a new page table base, so invalidate the TLB
-        * and I-stream.  This happens automatically everywhere but here.
-        */
-       ldiq    a0, -2                          /* TBIA */
-       call_pal PAL_OSF1_tbi
-       call_pal PAL_imb
-
-       /*
-        * All ready to go!  Call main()!
-        */
-       CALL(main)
-
-       /* This should never happen. */
-       PANIC("main() returned",Lmain_returned_pmsg)
-       END(__start)
-
 /**************************************************************************/
 
 /*
diff --git a/sys/arch/alpha/alpha/locore0.S b/sys/arch/alpha/alpha/locore0.S
new file mode 100644 (file)
index 0000000..9c6e5a7
--- /dev/null
@@ -0,0 +1,166 @@
+/* $OpenBSD: locore0.S,v 1.1 2017/06/05 17:49:05 deraadt Exp $ */
+/* $NetBSD: locore.s,v 1.94 2001/04/26 03:10:44 ross Exp $ */
+
+/*-
+ * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
+ * NASA Ames Research Center.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+.file  1 __FILE__
+
+#include <machine/asm.h>
+
+#include "assym.h"
+
+/*
+ * Perform actions necessary to switch to a new context.  The
+ * hwpcb should be in a0.  Clobbers v0, t0, t8..t11, a0.
+ */
+#define        SWITCH_CONTEXT                                                  \
+       /* Make a note of the context we're running on. */              \
+       GET_CURPCB                                              ;       \
+       stq     a0, 0(v0)                                       ;       \
+                                                                       \
+       /* Swap in the new context. */                                  \
+       call_pal PAL_OSF1_swpctx
+
+
+       /* don't reorder instructions; paranoia. */
+       .set noreorder
+       .text
+
+       .macro  bfalse  reg, dst
+       beq     \reg, \dst
+       .endm
+
+       .macro  btrue   reg, dst
+       bne     \reg, \dst
+       .endm
+
+#define        GET_CURPCB                                                      \
+       call_pal PAL_OSF1_rdval                                 ;       \
+       addq    v0, CPU_INFO_CURPCB, v0
+
+/*
+ * This is for kvm_mkdb, and should be the address of the beginning
+ * of the kernel text segment (not necessarily the same as kernbase).
+ */
+       EXPORT(kernel_text)
+.loc   1 __LINE__
+kernel_text:
+
+/*
+ * bootstack: a temporary stack, for booting.
+ *
+ * Extends from 'start' down.
+ */
+bootstack:
+
+/*
+ * __start: Kernel start.
+ *
+ * Arguments:
+ *     a0 is the first free page frame number (PFN) (no longer used)
+ *     a1 is the page table base register (PTBR)
+ *     a2 is the bootinfo magic number
+ *     a3 is the pointer to the bootinfo structure
+ *
+ * All arguments are passed to alpha_init().
+ */
+NESTED_NOPROFILE(__start,1,0,ra,0,0)
+       br      pv,Lstart1
+Lstart1: LDGP(pv)
+
+       /* Switch to the boot stack. */
+       lda     sp,bootstack
+
+       /* Load KGP with current GP. */
+       or      gp,zero,a0
+       call_pal PAL_OSF1_wrkgp         /* clobbers a0, t0, t8-t11 */
+
+       /*
+        * Call alpha_init() to do pre-main initialization.
+        * alpha_init() gets the arguments we were called with,
+        * which are already in a0 (destroyed), a1, a2, a3 and a4.
+        */
+       CALL(alpha_init)
+
+       /* Set up the virtual page table pointer. */
+       ldiq    a0, VPTBASE
+       call_pal PAL_OSF1_wrvptptr      /* clobbers a0, t0, t8-t11 */
+
+       /*
+        * Switch to proc0's PCB.
+        */
+       lda     a0, proc0
+       ldq     a0, P_MD_PCBPADDR(a0)           /* phys addr of PCB */
+       SWITCH_CONTEXT
+
+       /*
+        * We've switched to a new page table base, so invalidate the TLB
+        * and I-stream.  This happens automatically everywhere but here.
+        */
+       ldiq    a0, -2                          /* TBIA */
+       call_pal PAL_OSF1_tbi
+       call_pal PAL_imb
+
+       /*
+        * All ready to go!  Call main()!
+        */
+       CALL(main)
+
+       /* This should never happen. */
+       PANIC("main() returned",Lmain_returned_pmsg)
+       END(__start)
index 468ee69..fafd19c 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Makefile.alpha,v 1.97 2017/06/05 12:43:57 deraadt Exp $
+#      $OpenBSD: Makefile.alpha,v 1.98 2017/06/05 17:49:06 deraadt Exp $
 
 # For instructions on building kernels consult the config(8) and options(4)
 # manual pages.
@@ -31,9 +31,13 @@ CMACHFLAGS=  -mno-fp-regs -Wa,-mev56
 CMACHFLAGS+=   -fno-builtin-printf -fno-builtin-snprintf \
                -fno-builtin-vsnprintf -fno-builtin-log \
                -fno-builtin-log2 -fno-builtin-malloc ${NOPIE_FLAGS}
+SORTR=         sort -R
 .if ${IDENT:M-DNO_PROPOLICE}
 CMACHFLAGS+=   -fno-stack-protector
 .endif
+.if ${IDENT:M-DSMALL_KERNEL}
+SORTR=         cat
+.endif
 
 DEBUG?=                -g
 COPTS?=                -O2
@@ -67,13 +71,14 @@ NORMAL_S=   ${CC} ${AFLAGS} ${CPPFLAGS} -c $<
 #      ${SYSTEM_LD_HEAD}
 #      ${SYSTEM_LD} swapxxx.o
 #      ${SYSTEM_LD_TAIL}
-SYSTEM_HEAD=   locore.o param.o ioconf.o
-SYSTEM_OBJ=    ${SYSTEM_HEAD} ${OBJS}
+SYSTEM_HEAD=   locore0.o gap.o
+SYSTEM_OBJ=    ${SYSTEM_HEAD} ${OBJS} param.o ioconf.o
 SYSTEM_DEP=    Makefile ${SYSTEM_OBJ} ld.script
 SYSTEM_LD_HEAD=        @rm -f $@
 SYSTEM_LD=     @echo ${LD} ${LINKFLAGS} -o $@ '$${SYSTEM_HEAD} vers.o $${OBJS}'; \
                umask 007; \
-               ${LD} ${LINKFLAGS} -o $@ ${SYSTEM_HEAD} vers.o ${OBJS}
+               echo ${OBJS} param.o ioconf.o vers.o | tr " " "\n" | ${SORTR} > lorder; \
+               ${LD} ${LINKFLAGS} -o $@ ${SYSTEM_HEAD} `cat lorder`
 SYSTEM_LD_TAIL=        @${SIZE} $@
 
 .if ${DEBUG} == "-g"
@@ -120,8 +125,15 @@ vers.o: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP}
        sh $S/conf/newvers.sh
        ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c vers.c
 
+gap.S: ${SYSTEM_SWAP_DEP} Makefile
+       umask 007; sh $S/conf/makegap.sh 0x00 > gap.S
+
+gap.o: gap.S
+       umask 007; ${CC} ${AFLAGS} ${CPPFLAGS} ${PROF} -c gap.S
+
 clean:
-       rm -f *bsd *bsd.gdb *.[dio] [a-z]*.s assym.* ${DB_STRUCTINFO} param.c
+       rm -f *bsd *bsd.gdb *.[dio] [a-z]*.s assym.* ${DB_STRUCTINFO} \
+           gap.S lorder param.c
 
 cleandir: clean
        rm -f Makefile *.h ioconf.c options machine ${_mach} vers.c
@@ -133,6 +145,7 @@ db_structinfo.h: $S/ddb/db_structinfo.c $S/ddb/parse_structinfo.pl
        objdump -g db_structinfo.o | perl $S/ddb/parse_structinfo.pl > $@
        rm -f db_structinfo.o
 
+locore0.o: ${_machdir}/${_mach}/locore0.S assym.h
 locore.o: ${_machdir}/${_mach}/locore.s assym.h
 
 # The install target can be redefined by putting a
@@ -142,7 +155,7 @@ install: install-kernel-${MACHINE_NAME}
 .if !target(install-kernel-${MACHINE_NAME}})
 install-kernel-${MACHINE_NAME}:
        cmp -s bsd /bsd || ln -f /bsd /obsd
-       cp bsd /nbsd
+       cp -p bsd /nbsd
        mv /nbsd /bsd
 .endif
 
index 524be16..b4edb20 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: files.alpha,v 1.103 2016/01/08 15:54:12 jcs Exp $
+#      $OpenBSD: files.alpha,v 1.104 2017/06/05 17:49:06 deraadt Exp $
 #      $NetBSD: files.alpha,v 1.32 1996/11/25 04:03:21 cgd Exp $
 #
 # alpha-specific configuration info
@@ -297,6 +297,7 @@ file        arch/alpha/alpha/ipifuncs.c             multiprocessor
 file   arch/alpha/alpha/lock_machdep.c         multiprocessor
 file   arch/alpha/alpha/machdep.c
 file   arch/alpha/alpha/mainbus.c
+file   arch/alpha/alpha/locore.s
 file   arch/alpha/alpha/mem.c
 file   arch/alpha/alpha/pmap.c
 file   arch/alpha/alpha/process_machdep.c
index 07f0207..ee57f83 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: param.h,v 1.40 2016/09/03 14:25:27 bluhm Exp $ */
+/* $OpenBSD: param.h,v 1.41 2017/06/05 17:49:06 deraadt Exp $ */
 
 /*
  * Copyright (c) 1988 University of Utah.
 #define        MACHINE_ARCH    "alpha"
 #define        MID_MACHINE     MID_ALPHA
 
+#ifndef _LOCORE
 #ifdef _KERNEL
 #include <machine/cpu.h>
 #endif
+#endif
 
 #define        PAGE_SHIFT      13
 #define        PAGE_SIZE       (1 << PAGE_SHIFT)