ssp: add Object Size Checking common code
The Object Size Checking (-D_FORTIFY_SOURCE=*) functionality provides wrappers around functions suspectible to buffer overflows. While independent from Stack Smashing Protection (-fstack-protector*), they are often used and implemented together. While GCC also provides an implementation in libssp, it is completely broken (CVE-2016-4973, RHBZ#1324759) and seemingly unfixable, as there is no reliable way for a preprocessor macro to trigger a link flag. Therefore, adding this here is necessary to make it work. Note that this does require building gcc with --disable-libssp and gcc_cv_libc_provides_ssp=yes. Signed-off-by: Yaakov Selkowitz <yselkowi@redhat.com>
This commit is contained in:
		
							
								
								
									
										77
									
								
								newlib/libc/include/ssp/ssp.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								newlib/libc/include/ssp/ssp.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,77 @@ | ||||
| /*	$NetBSD: ssp.h,v 1.13 2015/09/03 20:43:47 plunky Exp $	*/ | ||||
|  | ||||
| /*- | ||||
|  * Copyright (c) 2006, 2011 The NetBSD Foundation, Inc. | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * This code is derived from software contributed to The NetBSD Foundation | ||||
|  * by Christos Zoulas. | ||||
|  * | ||||
|  * 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. | ||||
|  */ | ||||
| #ifndef _SSP_SSP_H_ | ||||
| #define _SSP_SSP_H_ | ||||
|  | ||||
| #include <sys/cdefs.h> | ||||
|  | ||||
| /* __ssp_real is used by the implementation in libc */ | ||||
| #if __SSP_FORTIFY_LEVEL == 0 | ||||
| #define __ssp_real_(fun)	fun | ||||
| #else | ||||
| #define __ssp_real_(fun)	__ssp_real_ ## fun | ||||
| #endif | ||||
| #define __ssp_real(fun)		__ssp_real_(fun) | ||||
|  | ||||
| #define __ssp_inline extern __inline__ __attribute__((__always_inline__, __gnu_inline__)) | ||||
|  | ||||
| #define __ssp_bos(ptr) __builtin_object_size(ptr, __SSP_FORTIFY_LEVEL > 1) | ||||
| #define __ssp_bos0(ptr) __builtin_object_size(ptr, 0) | ||||
|  | ||||
| #define __ssp_check(buf, len, bos) \ | ||||
| 	if (bos(buf) != (size_t)-1 && len > bos(buf)) \ | ||||
| 		__chk_fail() | ||||
| #define __ssp_decl(rtype, fun, args) \ | ||||
| rtype __ssp_real_(fun) args __asm__(__ASMNAME(#fun)); \ | ||||
| __ssp_inline rtype fun args __asm__(__ASMNAME("__ssp_protected_" #fun)); \ | ||||
| __ssp_inline rtype fun args | ||||
| #define __ssp_redirect_raw(rtype, fun, args, call, cond, bos) \ | ||||
| __ssp_decl(rtype, fun, args) \ | ||||
| { \ | ||||
| 	if (cond) \ | ||||
| 		__ssp_check(__buf, __len, bos); \ | ||||
| 	return __ssp_real_(fun) call; \ | ||||
| } | ||||
|  | ||||
| #define __ssp_redirect(rtype, fun, args, call) \ | ||||
|     __ssp_redirect_raw(rtype, fun, args, call, 1, __ssp_bos) | ||||
| #define __ssp_redirect0(rtype, fun, args, call) \ | ||||
|     __ssp_redirect_raw(rtype, fun, args, call, 1, __ssp_bos0) | ||||
|  | ||||
| #define __ssp_overlap(a, b, l) \ | ||||
|     (((a) <= (b) && (b) < (a) + (l)) || ((b) <= (a) && (a) < (b) + (l))) | ||||
|  | ||||
| __BEGIN_DECLS | ||||
| void __stack_chk_fail(void) __dead2; | ||||
| void __chk_fail(void) __dead2; | ||||
| __END_DECLS | ||||
|  | ||||
| #endif /* _SSP_SSP_H_ */ | ||||
| @@ -100,6 +100,9 @@ extern "C" { | ||||
|  * _SVID_SOURCE (deprecated by _DEFAULT_SOURCE) | ||||
|  * _DEFAULT_SOURCE (or none of the above) | ||||
|  * 	POSIX-1.2008 with BSD and SVr4 extensions | ||||
|  * | ||||
|  * _FORTIFY_SOURCE = 1 or 2 | ||||
|  * 	Object Size Checking function wrappers | ||||
|  */ | ||||
|  | ||||
| #ifdef _GNU_SOURCE | ||||
| @@ -233,9 +236,11 @@ extern "C" { | ||||
|  * __GNU_VISIBLE | ||||
|  * 	GNU extensions; enabled with _GNU_SOURCE. | ||||
|  * | ||||
|  * __SSP_FORTIFY_LEVEL | ||||
|  * 	Object Size Checking; defined to 0 (off), 1, or 2. | ||||
|  * | ||||
|  * In all cases above, "enabled by default" means either by defining | ||||
|  * _DEFAULT_SOURCE, or by not defining any of the public feature test macros. | ||||
|  * Defining _GNU_SOURCE makes all of the above avaliable. | ||||
|  */ | ||||
|  | ||||
| #ifdef _ATFILE_SOURCE | ||||
| @@ -314,6 +319,17 @@ extern "C" { | ||||
| #define	__XSI_VISIBLE		0 | ||||
| #endif | ||||
|  | ||||
| #if _FORTIFY_SOURCE > 0 && !defined(__cplusplus) && !defined(__lint__) && \ | ||||
|    (__OPTIMIZE__ > 0 || defined(__clang__)) && __GNUC_PREREQ__(4, 1) | ||||
| #  if _FORTIFY_SOURCE > 1 | ||||
| #    define __SSP_FORTIFY_LEVEL 2 | ||||
| #  else | ||||
| #    define __SSP_FORTIFY_LEVEL 1 | ||||
| #  endif | ||||
| #else | ||||
| #  define __SSP_FORTIFY_LEVEL 0 | ||||
| #endif | ||||
|  | ||||
| /* RTEMS adheres to POSIX -- 1003.1b with some features from annexes.  */ | ||||
|  | ||||
| #ifdef __rtems__ | ||||
|   | ||||
							
								
								
									
										13
									
								
								newlib/libc/ssp/chk_fail.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								newlib/libc/ssp/chk_fail.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| #include <signal.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| void | ||||
| __attribute__((__noreturn__)) | ||||
| __chk_fail(void) | ||||
| { | ||||
|   char msg[] = "*** buffer overflow detected ***: terminated\n"; | ||||
|   write (2, msg, strlen (msg)); | ||||
|   raise (SIGABRT); | ||||
|   _exit (127); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user