Index: etc/mtree/BSD.include.dist =================================================================== --- etc/mtree/BSD.include.dist +++ etc/mtree/BSD.include.dist @@ -321,6 +321,8 @@ mac_partition .. .. + secure + .. ssp .. sys Index: include/Makefile =================================================================== --- include/Makefile +++ include/Makefile @@ -6,7 +6,7 @@ .include CLEANFILES= osreldate.h version vers.c -SUBDIR= arpa protocols rpcsvc rpc xlocale +SUBDIR= arpa protocols rpcsvc rpc secure xlocale INCS= a.out.h ar.h assert.h bitstring.h complex.h cpio.h _ctype.h ctype.h \ db.h \ dirent.h dlfcn.h elf.h elf-hints.h err.h fmtmsg.h fnmatch.h fstab.h \ Index: include/secure/Makefile =================================================================== --- /dev/null +++ include/secure/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +INCS= security.h +INCSDIR= ${INCLUDEDIR}/secure + +.include Index: include/secure/security.h =================================================================== --- /dev/null +++ include/secure/security.h @@ -0,0 +1,93 @@ +/*- + * Copyright (c) 2015 Olivér Pintér + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#ifndef _SECURE_SECURITY_ +#define _SECURE_SECURITY_ + +#include +#include + +#ifndef __clang__ +#if __GNUC_PREREQ__(4, 3) +#define __errordecl(name, msg) extern void name(void) __error_attr(msg) +#else +#define __errordecl(name, msg) \ +static void name(void) __dead2; \ +static void name(void) \ +{ \ + \ + __fortify_chk_fail(msg); \ +} +#endif /* __GNUC_PREREQ(4, 3) */ +#else /* !__clang__ */ +#define __errordecl(name, msg) +#endif /* !__clang__ */ + +#define __RENAME(x) __asm__(#x) + +#if __has_builtin(__builtin_umul_overflow) || __GNUC_PREREQ__(5, 0) +#if __LP64__ +#define __size_mul_overflow(a, b, result) __builtin_umull_overflow(a, b, result) +#else +#define __size_mul_overflow(a, b, result) __builtin_umul_overflow(a, b, result) +#endif +#else +static __inline __always_inline int +__size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result) +{ + static const __SIZE_TYPE__ mul_no_overflow = 1UL << (sizeof(__SIZE_TYPE__) * 4); + + *result = a * b; + + return (a >= mul_no_overflow || b >= mul_no_overflow) && a > 0 && (__SIZE_TYPE__)-1 / a < b; +} +#endif + +static __inline __always_inline int +__fortify_chk_overlap(const char *a, const char *b, size_t len) +{ + + return ((uintptr_t)(a) < (uintptr_t)(b + len) && + (uintptr_t)(a + len) > (uintptr_t)(b)); +} + +__BEGIN_DECLS + +/* Common fail function. */ +void __secure_fail(const char *msg) __dead2 __nonnull(1); + +/* SSP related fail functions. */ +void __chk_fail(void) __dead2; +void __stack_chk_fail(void) __dead2; + +/* FORTIFY_SOURCE related fail function. */ +void __fortify_chk_fail(const char* msg) __dead2 __nonnull(1); + +__END_DECLS + +#endif /* !_SECURE_SECURITY_ */ Index: lib/libc/secure/Makefile.inc =================================================================== --- lib/libc/secure/Makefile.inc +++ lib/libc/secure/Makefile.inc @@ -6,7 +6,17 @@ # Sources common to both syscall interfaces: SRCS+= \ + fortify_source.c \ + secure_common.c \ stack_protector.c \ stack_protector_compat.c +# Sources which contains FORTIFY_SOURCE functions: +#SRCS+= + + +# Sources which contains FORTIFY_SOURCE functions, +# but live in .h files under sys/sys +#SRCS+= + SYM_MAPS+= ${LIBC_SRCTOP}/secure/Symbol.map Index: lib/libc/secure/Symbol.map =================================================================== --- lib/libc/secure/Symbol.map +++ lib/libc/secure/Symbol.map @@ -7,3 +7,20 @@ __stack_chk_fail; __stack_chk_guard; }; + +FBSD_1.1 { +}; + +FBSD_1.2 { +}; + +FBSD_1.3 { +}; + +FBSD_1.4 { + __fortify_chk_fail; + __secure_fail; +}; + +FBSDprivate_1.0 { +}; Index: lib/libc/secure/fortify_source.c =================================================================== --- /dev/null +++ lib/libc/secure/fortify_source.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2015 Olivér Pintér + * 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 AUTHOR 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 AUTHOR 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. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include "secure/security.h" + +void +__fortify_chk_fail(const char* msg) +{ + + __secure_fail(msg); +} + Index: lib/libc/secure/secure_common.c =================================================================== --- /dev/null +++ lib/libc/secure/secure_common.c @@ -0,0 +1,80 @@ +/* $NetBSD: stack_protector.c,v 1.4 2006/11/22 17:23:25 christos Exp $ */ +/* $OpenBSD: stack_protector.c,v 1.10 2006/03/31 05:34:44 deraadt Exp $ */ +/* + * Copyright (c) 2002 Hiroaki Etoh, Federico G. Schwindt, and Miodrag Vallat. + * 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 AUTHORS ``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 AUTHORS 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. + * + */ + +#undef _FORTIFY_SOURCE + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "un-namespace.h" + +#include "libc_private.h" + +static void __fail(const char *) __dead2; + +/*ARGSUSED*/ +static void +__fail(const char *msg) +{ + struct sigaction sa; + sigset_t mask; + + /* Immediately block all signal handlers from running code */ + (void)sigfillset(&mask); + (void)sigdelset(&mask, SIGABRT); + (void)_sigprocmask(SIG_BLOCK, &mask, NULL); + + /* This may fail on a chroot jail... */ + syslog(LOG_CRIT, "%s", msg); + + (void)memset(&sa, 0, sizeof(sa)); + (void)sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + (void)sigaction(SIGABRT, &sa, NULL); + (void)kill(getpid(), SIGABRT); + _exit(127); +} + +void +__secure_fail(const char *msg) +{ + + __fail(msg); +} Index: lib/libc/secure/stack_protector.c =================================================================== --- lib/libc/secure/stack_protector.c +++ lib/libc/secure/stack_protector.c @@ -33,12 +33,8 @@ #include #include #include -#include +#include #include -#include -#include -#include -#include #include "libc_private.h" extern int __sysctl(const int *name, u_int namelen, void *oldp, @@ -46,9 +42,7 @@ long __stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; static void __guard_setup(void) __attribute__((__constructor__, __used__)); -static void __fail(const char *); -void __stack_chk_fail(void); -void __chk_fail(void); +void __stack_chk_fail(void) __dead2; /*LINTED used*/ static void @@ -76,40 +70,18 @@ } } -/*ARGSUSED*/ -static void -__fail(const char *msg) -{ - struct sigaction sa; - sigset_t mask; - - /* Immediately block all signal handlers from running code */ - (void)sigfillset(&mask); - (void)sigdelset(&mask, SIGABRT); - (void)sigprocmask(SIG_BLOCK, &mask, NULL); - - /* This may fail on a chroot jail... */ - syslog(LOG_CRIT, "%s", msg); - - (void)memset(&sa, 0, sizeof(sa)); - (void)sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - (void)sigaction(SIGABRT, &sa, NULL); - (void)kill(getpid(), SIGABRT); - _exit(127); -} - void __stack_chk_fail(void) { - __fail("stack overflow detected; terminated"); + + __secure_fail("stack overflow detected; terminated"); } void __chk_fail(void) { - __fail("buffer overflow detected; terminated"); + + __secure_fail("buffer overflow detected; terminated"); } #ifndef PIC Index: share/mk/bsd.opts.mk =================================================================== --- share/mk/bsd.opts.mk +++ share/mk/bsd.opts.mk @@ -68,6 +68,7 @@ __DEFAULT_NO_OPTIONS = \ CTF \ DEBUG_FILES \ + FORTIFY \ INSTALL_AS_USER \ STALE_STAGED Index: share/mk/bsd.sys.mk =================================================================== --- share/mk/bsd.sys.mk +++ share/mk/bsd.sys.mk @@ -153,6 +153,16 @@ CFLAGS+= ${SSP_CFLAGS} .endif # SSP && !ARM && !MIPS +# Allow to override the MK_FORTIFY settings per compiler basis. +.if defined(MK_FORTIFY.${COMPILER_TYPE}) +MK_FORTIFY= ${MK_FORTIFY.${COMPILER_TYPE}} +.endif + +.if ${MK_FORTIFY} != "no" +FORTIFY_CFLAGS?= -D_FORTIFY_SOURCE=1 +CFLAGS+= ${FORTIFY_CFLAGS} +.endif # FORTIFY + # Allow user-specified additional warning flags, plus compiler specific flag overrides. # Unless we've overriden this... .if ${MK_WARNS} != "no" Index: sys/sys/cdefs.h =================================================================== --- sys/sys/cdefs.h +++ sys/sys/cdefs.h @@ -545,6 +545,26 @@ #define __gnu_inline #endif +#if __has_attribute(error) || __GNUC_PREREQ__(4, 3) +#define __error_attr(msg) __attribute__((__error__(msg))) +#else +#define __error_attr(msg) +#endif + +/* FORTIFY_SOURCE related defines. */ +#if __GNUC_PREREQ__(4, 1) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && \ + defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 && !defined(lint) +#define __BSD_FORTIFY 1 +#if _FORTIFY_SOURCE >= 2 +#define __bos(s) __builtin_object_size((s), 1) +#else +#define __bos(s) __builtin_object_size((s), 0) +#endif +#define __bos0(s) __builtin_object_size((s), 0) +#define __FORTIFY_INLINE extern __inline __always_inline __gnu_inline +#endif /* !_FORTIFY_SOURCE */ +#define __FORTIFY_UNKNOWN_SIZE ((size_t) -1) + /* Compiler-dependent macros that rely on FreeBSD-specific extensions. */ #if defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 300001 && \ defined(__GNUC__) && !defined(__INTEL_COMPILER) Index: tools/build/options/WITH_FORTIFY =================================================================== --- /dev/null +++ tools/build/options/WITH_FORTIFY @@ -0,0 +1,4 @@ +.\" $FreeBSD$ +Set to not build world with FORTIFY_SOURCE. + +FORTIFY_SOURCE is a libc feature provides primitive support for detecting buffer overflows in various functions which operate on memory areas and strings. A limited set of buffer overflows can be detected with this feature, but it provides an additional level of validation for some functions which are the origin of buffer overflow flaws.