1be04fec4SKyle Evans /* $NetBSD: ssp.h,v 1.13 2015/09/03 20:43:47 plunky Exp $ */ 2be04fec4SKyle Evans 3be04fec4SKyle Evans /*- 4be04fec4SKyle Evans * 5be04fec4SKyle Evans * SPDX-License-Identifier: BSD-2-Clause 6be04fec4SKyle Evans * 7be04fec4SKyle Evans * Copyright (c) 2006, 2011 The NetBSD Foundation, Inc. 8be04fec4SKyle Evans * All rights reserved. 9be04fec4SKyle Evans * 10be04fec4SKyle Evans * This code is derived from software contributed to The NetBSD Foundation 11be04fec4SKyle Evans * by Christos Zoulas. 12be04fec4SKyle Evans * 13be04fec4SKyle Evans * Redistribution and use in source and binary forms, with or without 14be04fec4SKyle Evans * modification, are permitted provided that the following conditions 15be04fec4SKyle Evans * are met: 16be04fec4SKyle Evans * 1. Redistributions of source code must retain the above copyright 17be04fec4SKyle Evans * notice, this list of conditions and the following disclaimer. 18be04fec4SKyle Evans * 2. Redistributions in binary form must reproduce the above copyright 19be04fec4SKyle Evans * notice, this list of conditions and the following disclaimer in the 20be04fec4SKyle Evans * documentation and/or other materials provided with the distribution. 21be04fec4SKyle Evans * 22be04fec4SKyle Evans * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23be04fec4SKyle Evans * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24be04fec4SKyle Evans * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25be04fec4SKyle Evans * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26be04fec4SKyle Evans * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27be04fec4SKyle Evans * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28be04fec4SKyle Evans * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29be04fec4SKyle Evans * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30be04fec4SKyle Evans * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31be04fec4SKyle Evans * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32be04fec4SKyle Evans * POSSIBILITY OF SUCH DAMAGE. 33be04fec4SKyle Evans */ 34be04fec4SKyle Evans #ifndef _SSP_SSP_H_ 35be04fec4SKyle Evans #define _SSP_SSP_H_ 36be04fec4SKyle Evans 37be04fec4SKyle Evans #include <sys/cdefs.h> 38be04fec4SKyle Evans 39be04fec4SKyle Evans #if !defined(__cplusplus) 40be04fec4SKyle Evans # if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && \ 41be04fec4SKyle Evans (__OPTIMIZE__ > 0 || defined(__clang__)) 42be04fec4SKyle Evans # if _FORTIFY_SOURCE > 1 43be04fec4SKyle Evans # define __SSP_FORTIFY_LEVEL 2 44be04fec4SKyle Evans # else 45be04fec4SKyle Evans # define __SSP_FORTIFY_LEVEL 1 46be04fec4SKyle Evans # endif 47be04fec4SKyle Evans # else 48be04fec4SKyle Evans # define __SSP_FORTIFY_LEVEL 0 49be04fec4SKyle Evans # endif 50be04fec4SKyle Evans #else 51be04fec4SKyle Evans # define __SSP_FORTIFY_LEVEL 0 52be04fec4SKyle Evans #endif 53be04fec4SKyle Evans 54be04fec4SKyle Evans #define __ssp_var(type) __CONCAT(__ssp_ ## type, __COUNTER__) 55be04fec4SKyle Evans 56be04fec4SKyle Evans /* __ssp_real is used by the implementation in libc */ 57be04fec4SKyle Evans #if __SSP_FORTIFY_LEVEL == 0 58be04fec4SKyle Evans #define __ssp_real_(fun) fun 59be04fec4SKyle Evans #else 60be04fec4SKyle Evans #define __ssp_real_(fun) __ssp_real_ ## fun 61be04fec4SKyle Evans #endif 62be04fec4SKyle Evans #define __ssp_real(fun) __ssp_real_(fun) 63be04fec4SKyle Evans 64be04fec4SKyle Evans #define __ssp_inline static __inline __attribute__((__always_inline__)) 65be04fec4SKyle Evans 66be04fec4SKyle Evans #define __ssp_bos(ptr) __builtin_object_size(ptr, __SSP_FORTIFY_LEVEL > 1) 67be04fec4SKyle Evans #define __ssp_bos0(ptr) __builtin_object_size(ptr, 0) 68be04fec4SKyle Evans 69be04fec4SKyle Evans #define __ssp_check(buf, len, bos) \ 70cf8e5289SKyle Evans if (bos(buf) != (size_t)-1 && (size_t)len > bos(buf)) \ 71be04fec4SKyle Evans __chk_fail() 72cf8e5289SKyle Evans 73cf8e5289SKyle Evans #define __ssp_redirect_raw_impl(rtype, fun, symbol, args) \ 74be04fec4SKyle Evans rtype __ssp_real_(fun) args __RENAME(symbol); \ 75be04fec4SKyle Evans __ssp_inline rtype fun args __RENAME(__ssp_protected_ ## fun); \ 76cf8e5289SKyle Evans __ssp_inline rtype fun args 77cf8e5289SKyle Evans 78cf8e5289SKyle Evans #define __ssp_redirect_raw(rtype, fun, symbol, args, call, cond, bos, len) \ 79cf8e5289SKyle Evans __ssp_redirect_raw_impl(rtype, fun, symbol, args) { \ 80be04fec4SKyle Evans if (cond) \ 81cf8e5289SKyle Evans __ssp_check(__buf, len, bos); \ 82be04fec4SKyle Evans return __ssp_real_(fun) call; \ 83be04fec4SKyle Evans } 84be04fec4SKyle Evans 85be04fec4SKyle Evans #define __ssp_redirect(rtype, fun, args, call) \ 86cf8e5289SKyle Evans __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos, __len) 87be04fec4SKyle Evans #define __ssp_redirect0(rtype, fun, args, call) \ 88cf8e5289SKyle Evans __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos0, __len) 89be04fec4SKyle Evans 90c10d567eSKyle Evans #include <machine/_stdint.h> 91c10d567eSKyle Evans 92c10d567eSKyle Evans static inline int 93c10d567eSKyle Evans __ssp_overlap(const void *leftp, const void *rightp, __size_t sz) 94c10d567eSKyle Evans { 95c10d567eSKyle Evans __uintptr_t left = (__uintptr_t)leftp; 96c10d567eSKyle Evans __uintptr_t right = (__uintptr_t)rightp; 97c10d567eSKyle Evans 98c10d567eSKyle Evans if (left <= right) 99c10d567eSKyle Evans return (SIZE_MAX - sz < left || right < left + sz); 100c10d567eSKyle Evans 101c10d567eSKyle Evans return (SIZE_MAX - sz < right || left < right + sz); 102c10d567eSKyle Evans } 10347193661SKyle Evans 104*1ace24b3SKyle Evans #include <sys/_iovec.h> 105*1ace24b3SKyle Evans 106be04fec4SKyle Evans __BEGIN_DECLS 107be04fec4SKyle Evans void __stack_chk_fail(void) __dead2; 108be04fec4SKyle Evans void __chk_fail(void) __dead2; 109be04fec4SKyle Evans __END_DECLS 110be04fec4SKyle Evans 111*1ace24b3SKyle Evans __ssp_inline void 112*1ace24b3SKyle Evans __ssp_check_iovec(const struct iovec *iov, int iovcnt) 113*1ace24b3SKyle Evans { 114*1ace24b3SKyle Evans const size_t iovsz = __ssp_bos(iov); 115*1ace24b3SKyle Evans 116*1ace24b3SKyle Evans if (iovsz != (size_t)-1 && iovsz / sizeof(*iov) < (size_t)iovcnt) 117*1ace24b3SKyle Evans __chk_fail(); 118*1ace24b3SKyle Evans 119*1ace24b3SKyle Evans for (int i = 0; i < iovcnt; i++) { 120*1ace24b3SKyle Evans if (__ssp_bos(iov[i].iov_base) < iov[i].iov_len) 121*1ace24b3SKyle Evans __chk_fail(); 122*1ace24b3SKyle Evans } 123*1ace24b3SKyle Evans } 124*1ace24b3SKyle Evans 125be04fec4SKyle Evans #endif /* _SSP_SSP_H_ */ 126