From 160a37667a8130b0b9de3a1669ae46983ea440a6 Mon Sep 17 00:00:00 2001 From: christos Date: Thu, 12 Feb 2009 18:24:18 +0000 Subject: [PATCH] Unbreak ssp kernels. The issue here that when the ssp_init() call was deferred, it caused the return from the enclosing function to break, as well as the ssp return on i386. To fix both issues, split configure in two pieces the one before calling ssp_init and the one after, and move the ssp_init() call back in main. Put ssp_init() in its own file, and compile this new file with -fno-stack-protector. Tested on amd64. XXX: If we want to have ssp kernels working on 5.0, this change needs to be pulled up. --- sys/conf/Makefile.kern.inc | 3 +- sys/conf/files | 3 +- sys/kern/init_main.c | 54 +++----------------------- sys/kern/kern_ssp.c | 77 ++++++++++++++++++++++++++++++++++++++ sys/kern/subr_autoconf.c | 18 ++++----- sys/sys/device.h | 3 +- sys/sys/systm.h | 4 +- 7 files changed, 101 insertions(+), 61 deletions(-) create mode 100644 sys/kern/kern_ssp.c diff --git a/sys/conf/Makefile.kern.inc b/sys/conf/Makefile.kern.inc index b30c8afe8162..7fb099ef3cbd 100644 --- a/sys/conf/Makefile.kern.inc +++ b/sys/conf/Makefile.kern.inc @@ -1,4 +1,4 @@ -# $NetBSD: Makefile.kern.inc,v 1.120 2009/01/18 13:53:03 hans Exp $ +# $NetBSD: Makefile.kern.inc,v 1.121 2009/02/12 18:24:18 christos Exp $ # # This file contains common `MI' targets and definitions and it is included # at the bottom of each `MD' ${MACHINE}/conf/Makefile.${MACHINE}. @@ -95,6 +95,7 @@ CFLAGS+= -fno-strict-aliasing .if ${USE_SSP:Uno} == "yes" CFLAGS+=-fstack-protector -Wstack-protector --param ssp-buffer-size=1 LDFLAGS+=-fstack-protector -Wstack-protector --param ssp-buffer-size=1 +COPTS.kern_ssp.c+= -fno-stack-protector -D__SSP__ .endif # If we want the bpendtsleep: label in kern_synch.c, we need to use diff --git a/sys/conf/files b/sys/conf/files index 402a6e45f7f2..108d58108433 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.939 2009/02/06 18:50:29 jym Exp $ +# $NetBSD: files,v 1.940 2009/02/12 18:24:18 christos Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 version 20081219 @@ -1423,6 +1423,7 @@ file kern/kern_rwlock.c file kern/kern_sig.c file kern/kern_sleepq.c file kern/kern_softint.c +file kern/kern_ssp.c file kern/kern_stub.c file kern/kern_subr.c file kern/kern_synch.c diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 9a9405ca4b3c..6cc4dcfb93e2 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.380 2009/01/11 02:45:51 christos Exp $ */ +/* $NetBSD: init_main.c,v 1.381 2009/02/12 18:24:18 christos Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -97,7 +97,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.380 2009/01/11 02:45:51 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.381 2009/02/12 18:24:18 christos Exp $"); #include "opt_ddb.h" #include "opt_ipsec.h" @@ -253,52 +253,6 @@ int start_init_exec; /* semaphore for start_init() */ static void check_console(struct lwp *l); static void start_init(void *); void main(void); -void ssp_init(void); - -#if defined(__SSP__) || defined(__SSP_ALL__) -long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; -void __stack_chk_fail(void); - -void -__stack_chk_fail(void) -{ - panic("stack overflow detected; terminated"); -} - -void -ssp_init(void) -{ - int s; - -#ifdef DIAGNOSTIC - printf("Initializing SSP:"); -#endif - /* - * We initialize ssp here carefully: - * 1. after we got some entropy - * 2. without calling a function - */ - size_t i; - long guard[__arraycount(__stack_chk_guard)]; - - arc4randbytes(guard, sizeof(guard)); - s = splhigh(); - for (i = 0; i < __arraycount(guard); i++) - __stack_chk_guard[i] = guard[i]; - splx(s); -#ifdef DIAGNOSTIC - for (i = 0; i < __arraycount(guard); i++) - printf("%lx ", guard[i]); - printf("\n"); -#endif -} -#else -void -ssp_init(void) -{ - -} -#endif void __secmodel_none(void); __weak_alias(secmodel_start,__secmodel_none); @@ -513,6 +467,10 @@ main(void) /* Configure the system hardware. This will enable interrupts. */ configure(); + ssp_init(); + + configure2(); + ubc_init(); /* must be after autoconfig */ #ifdef SYSVSHM diff --git a/sys/kern/kern_ssp.c b/sys/kern/kern_ssp.c new file mode 100644 index 000000000000..3296db8acfc5 --- /dev/null +++ b/sys/kern/kern_ssp.c @@ -0,0 +1,77 @@ +/* $NetBSD: kern_ssp.c,v 1.1 2009/02/12 18:24:18 christos Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * 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. + */ + +#include +__KERNEL_RCSID(0, "$NetBSD: kern_ssp.c,v 1.1 2009/02/12 18:24:18 christos Exp $"); + +#include +#include + +#if defined(__SSP__) || defined(__SSP_ALL__) +long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; +void __stack_chk_fail(void); + +void +__stack_chk_fail(void) +{ + panic("stack overflow detected; terminated"); +} + +void +ssp_init(void) +{ + int s; + +#ifdef DIAGNOSTIC + printf("Initializing SSP:"); +#endif + /* + * We initialize ssp here carefully: + * 1. after we got some entropy + * 2. without calling a function + */ + size_t i; + long guard[__arraycount(__stack_chk_guard)]; + + arc4randbytes(guard, sizeof(guard)); + s = splhigh(); + for (i = 0; i < __arraycount(guard); i++) + __stack_chk_guard[i] = guard[i]; + splx(s); +#ifdef DIAGNOSTIC + for (i = 0; i < __arraycount(guard); i++) + printf("%lx ", guard[i]); + printf("\n"); +#endif +} +#else +void +ssp_init(void) +{ +} +#endif diff --git a/sys/kern/subr_autoconf.c b/sys/kern/subr_autoconf.c index 85e9162e6b8e..947dbeb4bfe1 100644 --- a/sys/kern/subr_autoconf.c +++ b/sys/kern/subr_autoconf.c @@ -1,4 +1,4 @@ -/* $NetBSD: subr_autoconf.c,v 1.167 2008/12/29 13:40:11 ad Exp $ */ +/* $NetBSD: subr_autoconf.c,v 1.168 2009/02/12 18:24:18 christos Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -77,7 +77,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.167 2008/12/29 13:40:11 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.168 2009/02/12 18:24:18 christos Exp $"); #include "opt_ddb.h" #include "drvctl.h" @@ -411,11 +411,6 @@ config_interrupts_thread(void *cookie) void configure(void) { - extern void ssp_init(void); - CPU_INFO_ITERATOR cii; - struct cpu_info *ci; - int i, s; - /* Initialize data structures. */ config_init(); pmf_init(); @@ -440,9 +435,14 @@ configure(void) * to be enabled. */ cpu_configure(); +} - /* Initialize SSP. */ - ssp_init(); +void +configure2(void) +{ + CPU_INFO_ITERATOR cii; + struct cpu_info *ci; + int i, s; /* * Now that we've found all the hardware, start the real time diff --git a/sys/sys/device.h b/sys/sys/device.h index 0b25f7838486..49138ad83b70 100644 --- a/sys/sys/device.h +++ b/sys/sys/device.h @@ -1,4 +1,4 @@ -/* $NetBSD: device.h,v 1.115 2008/11/13 21:15:01 dyoung Exp $ */ +/* $NetBSD: device.h,v 1.116 2009/02/12 18:24:18 christos Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -396,6 +396,7 @@ int config_handle_wedges(struct device *, int); void config_init(void); void drvctl_init(void); void configure(void); +void configure2(void); int config_cfdriver_attach(struct cfdriver *); int config_cfdriver_detach(struct cfdriver *); diff --git a/sys/sys/systm.h b/sys/sys/systm.h index bdc74f8b4d32..07d0014acfc2 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -1,4 +1,4 @@ -/* $NetBSD: systm.h,v 1.232 2008/12/19 17:11:57 pgoyette Exp $ */ +/* $NetBSD: systm.h,v 1.233 2009/02/12 18:24:18 christos Exp $ */ /*- * Copyright (c) 1982, 1988, 1991, 1993 @@ -287,6 +287,8 @@ void hardpps(struct timespec *, long); void ntp_init(void); /* also provides adjtime() functionality */ #endif /* NTP */ +void ssp_init(void); + void initclocks(void); void inittodr(time_t); void resettodr(void);