diff --git a/include/ssp/string.h b/include/ssp/string.h index b9f2dceb1df5..9f24254d9c01 100644 --- a/include/ssp/string.h +++ b/include/ssp/string.h @@ -1,151 +1,139 @@ /* $NetBSD: string.h,v 1.14 2020/09/05 13:37:59 mrg Exp $ */ /*- * * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2006 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_STRING_H_ #define _SSP_STRING_H_ #include __BEGIN_DECLS void *__memcpy_chk(void *, const void *, size_t, size_t); void *__memmove_chk(void *, const void *, size_t, size_t); void *__memset_chk(void *, int, size_t, size_t); char *__stpcpy_chk(char *, const char *, size_t); char *__stpncpy_chk(char *, const char *, size_t, size_t); char *__strcat_chk(char *, const char *, size_t); char *__strcpy_chk(char *, const char *, size_t); char *__strncat_chk(char *, const char *, size_t, size_t); size_t __strlcat_chk(char *, const char *, size_t, size_t); char *__strncpy_chk(char *, const char *, size_t, size_t); size_t __strlcpy_chk(char *, const char *, size_t, size_t); __END_DECLS #if __SSP_FORTIFY_LEVEL > 0 #define __ssp_bos_check3_typed_var(fun, dsttype, dsrvar, dst, srctype, srcvar, \ src, lenvar, len) __extension__ ({ \ srctype srcvar = (src); \ dsttype dstvar = (dst); \ size_t lenvar = (len); \ ((__ssp_bos0(dstvar) != (size_t)-1) ? \ __builtin___ ## fun ## _chk(dstvar, srcvar, lenvar, \ __ssp_bos0(dstvar)) : \ __ ## fun ## _ichk(dstvar, srcvar, lenvar)); \ }) #define __ssp_bos_check3_typed(fun, dsttype, dst, srctype, src, len) \ __ssp_bos_check3_typed_var(fun, dsttype, __ssp_var(dstv), dst, \ srctype, __ssp_var(srcv), src, __ssp_var(lenv), len) #define __ssp_bos_check3(fun, dst, src, len) \ __ssp_bos_check3_typed_var(fun, void *, __ssp_var(dstv), dst, \ const void *, __ssp_var(srcv), src, __ssp_var(lenv), len) #define __ssp_bos_check2_var(fun, dstvar, dst, srcvar, src) __extension__ ({ \ const void *srcvar = (src); \ void *dstvar = (dst); \ ((__ssp_bos0(dstvar) != (size_t)-1) ? \ __builtin___ ## fun ## _chk(dstvar, srcvar, \ __ssp_bos0(dstvar)) : \ __ ## fun ## _ichk(dstvar, srcvar)); \ }) #define __ssp_bos_check2(fun, dst, src) \ __ssp_bos_check2_var(fun, __ssp_var(dstv), dst, __ssp_var(srcv), src) #define __ssp_bos_icheck3_restrict(fun, type1, type2) \ static __inline type1 __ ## fun ## _ichk(type1 __restrict, type2 __restrict, size_t); \ static __inline __attribute__((__always_inline__)) type1 \ __ ## fun ## _ichk(type1 __restrict dst, type2 __restrict src, size_t len) { \ return __builtin___ ## fun ## _chk(dst, src, len, __ssp_bos0(dst)); \ } #define __ssp_bos_icheck3(fun, type1, type2) \ static __inline type1 __ ## fun ## _ichk(type1, type2, size_t); \ static __inline __attribute__((__always_inline__)) type1 \ __ ## fun ## _ichk(type1 dst, type2 src, size_t len) { \ return __builtin___ ## fun ## _chk(dst, src, len, __ssp_bos0(dst)); \ } #define __ssp_bos_icheck2_restrict(fun, type1, type2) \ static __inline type1 __ ## fun ## _ichk(type1, type2); \ static __inline __attribute__((__always_inline__)) type1 \ __ ## fun ## _ichk(type1 __restrict dst, type2 __restrict src) { \ return __builtin___ ## fun ## _chk(dst, src, __ssp_bos0(dst)); \ } __BEGIN_DECLS __ssp_bos_icheck3_restrict(memcpy, void *, const void *) +__ssp_bos_icheck3_restrict(mempcpy, void *, const void *) __ssp_bos_icheck3(memmove, void *, const void *) __ssp_bos_icheck3(memset, void *, int) __ssp_bos_icheck2_restrict(stpcpy, char *, const char *) __ssp_bos_icheck3_restrict(stpncpy, char *, const char *) __ssp_bos_icheck2_restrict(strcpy, char *, const char *) __ssp_bos_icheck2_restrict(strcat, char *, const char *) __ssp_redirect0(int, strerror_r, (int __errnum, char *__buf, size_t __len), (__errnum, __buf, __len)); __ssp_bos_icheck3_restrict(strncpy, char *, const char *) __ssp_bos_icheck3_restrict(strncat, char *, const char *) - -__ssp_redirect_raw_impl(void *, mempcpy, mempcpy, - (void *__restrict buf, const void *__restrict src, size_t len)) -{ - const size_t slen = __ssp_bos(buf); - - if (len > slen) - __chk_fail(); - - if (__ssp_overlap(src, buf, len)) - __chk_fail(); - - return (__ssp_real(mempcpy)(buf, src, len)); -} __END_DECLS #define memcpy(dst, src, len) __ssp_bos_check3(memcpy, dst, src, len) +#define mempcpy(dst, src, len) __ssp_bos_check3(mempcpy, dst, src, len) #define memmove(dst, src, len) __ssp_bos_check3(memmove, dst, src, len) #define memset(dst, val, len) \ __ssp_bos_check3_typed(memset, void *, dst, int, val, len) #define stpcpy(dst, src) __ssp_bos_check2(stpcpy, dst, src) #define stpncpy(dst, src, len) __ssp_bos_check3(stpncpy, dst, src, len) #define strcpy(dst, src) __ssp_bos_check2(strcpy, dst, src) #define strcat(dst, src) __ssp_bos_check2(strcat, dst, src) #define strlcpy(dst, src, dstlen) \ __strlcpy_chk(dst, src, dstlen, __ssp_bos(dst)) #define strncpy(dst, src, len) __ssp_bos_check3(strncpy, dst, src, len) #define strlcat(dst, src, dstlen) \ __strlcat_chk(dst, src, dstlen, __ssp_bos(dst)) #define strncat(dst, src, len) __ssp_bos_check3(strncat, dst, src, len) #endif /* __SSP_FORTIFY_LEVEL > 0 */ #endif /* _SSP_STRING_H_ */ diff --git a/include/string.h b/include/string.h index c9d3e1add1a1..d9adcf4e0e41 100644 --- a/include/string.h +++ b/include/string.h @@ -1,175 +1,175 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. 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. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 _STRING_H_ #define _STRING_H_ #include #include #include /* * Prototype functions which were historically defined in , but * are required by POSIX to be prototyped in . */ #if __BSD_VISIBLE #include #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 #include #endif __BEGIN_DECLS #if __XSI_VISIBLE >= 600 void *memccpy(void * __restrict, const void * __restrict, int, size_t); #endif void *memchr(const void *, int, size_t) __pure; #if __BSD_VISIBLE void *memrchr(const void *, int, size_t) __pure; #endif int memcmp(const void *, const void *, size_t) __pure; void *(memcpy)(void * __restrict, const void * __restrict, size_t); #if __BSD_VISIBLE void *memmem(const void *, size_t, const void *, size_t) __pure; #endif void *(memmove)(void *, const void *, size_t); #if __BSD_VISIBLE -void *mempcpy(void * __restrict, const void * __restrict, size_t); +void *(mempcpy)(void * __restrict, const void * __restrict, size_t); #endif void *(memset)(void *, int, size_t); #if __POSIX_VISIBLE >= 200809 char *(stpcpy)(char * __restrict, const char * __restrict); char *(stpncpy)(char * __restrict, const char * __restrict, size_t); #endif #if __BSD_VISIBLE char *strcasestr(const char *, const char *) __pure; #endif char *(strcat)(char * __restrict, const char * __restrict); char *strchr(const char *, int) __pure; #if __BSD_VISIBLE char *strchrnul(const char*, int) __pure; int strverscmp(const char *, const char *) __pure; #endif int strcmp(const char *, const char *) __pure; int strcoll(const char *, const char *); char *(strcpy)(char * __restrict, const char * __restrict); size_t strcspn(const char *, const char *) __pure; #if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE char *strdup(const char *) __malloc_like; #endif char *strerror(int); #if __POSIX_VISIBLE >= 200112 int strerror_r(int, char *, size_t); #endif #if __BSD_VISIBLE size_t (strlcat)(char * __restrict, const char * __restrict, size_t); size_t (strlcpy)(char * __restrict, const char * __restrict, size_t); #endif size_t strlen(const char *) __pure; #if __BSD_VISIBLE #ifndef _MODE_T_DECLARED typedef __mode_t mode_t; #define _MODE_T_DECLARED #endif void strmode(mode_t, char *); #endif char *(strncat)(char * __restrict, const char * __restrict, size_t); int strncmp(const char *, const char *, size_t) __pure; char *(strncpy)(char * __restrict, const char * __restrict, size_t); #if __POSIX_VISIBLE >= 200809 char *strndup(const char *, size_t) __malloc_like; size_t strnlen(const char *, size_t) __pure; #endif #if __BSD_VISIBLE char *strnstr(const char *, const char *, size_t) __pure; #endif char *strpbrk(const char *, const char *) __pure; char *strrchr(const char *, int) __pure; #if __BSD_VISIBLE char *strsep(char **, const char *); #endif #if __POSIX_VISIBLE >= 200809 char *strsignal(int); #endif size_t strspn(const char *, const char *) __pure; char *strstr(const char *, const char *) __pure; char *strtok(char * __restrict, const char * __restrict); #if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE >= 500 char *strtok_r(char *, const char *, char **); #endif size_t strxfrm(char * __restrict, const char * __restrict, size_t); #if __BSD_VISIBLE #ifndef _SWAB_DECLARED #define _SWAB_DECLARED #ifndef _SSIZE_T_DECLARED typedef __ssize_t ssize_t; #define _SSIZE_T_DECLARED #endif /* _SIZE_T_DECLARED */ void swab(const void * __restrict, void * __restrict, ssize_t); #endif /* _SWAB_DECLARED */ int timingsafe_bcmp(const void *, const void *, size_t); int timingsafe_memcmp(const void *, const void *, size_t); #endif /* __BSD_VISIBLE */ #if __POSIX_VISIBLE >= 200112 || defined(_XLOCALE_H_) #include #endif #if __EXT1_VISIBLE #ifndef _RSIZE_T_DEFINED #define _RSIZE_T_DEFINED typedef size_t rsize_t; #endif #ifndef _ERRNO_T_DEFINED #define _ERRNO_T_DEFINED typedef int errno_t; #endif /* ISO/IEC 9899:2011 K.3.7.4.1.1 */ errno_t memset_s(void *, rsize_t, int, rsize_t); #endif /* __EXT1_VISIBLE */ __END_DECLS #endif /* _STRING_H_ */ diff --git a/lib/libc/secure/Makefile.inc b/lib/libc/secure/Makefile.inc index 5d10612e67a8..e5286a5a380f 100644 --- a/lib/libc/secure/Makefile.inc +++ b/lib/libc/secure/Makefile.inc @@ -1,21 +1,21 @@ # # libc sources related to security .PATH: ${LIBC_SRCTOP}/secure # _FORTIFY_SOURCE -SRCS+= fgets_chk.c memcpy_chk.c memmove_chk.c memset_chk.c \ +SRCS+= fgets_chk.c memcpy_chk.c memmove_chk.c mempcpy_chk.c memset_chk.c \ snprintf_chk.c sprintf_chk.c stpcpy_chk.c stpncpy_chk.c \ strcat_chk.c strcpy_chk.c strlcat_chk.c strncat_chk.c strlcpy_chk.c \ strncpy_chk.c vsnprintf_chk.c vsprintf_chk.c CFLAGS.snprintf_chk.c+= -Wno-unused-parameter CFLAGS.sprintf_chk.c+= -Wno-unused-parameter CFLAGS.vsnprintf_chk.c+= -Wno-unused-parameter CFLAGS.vsprintf_chk.c+= -Wno-unused-parameter # Sources common to both syscall interfaces: SRCS+= stack_protector.c \ stack_protector_compat.c SYM_MAPS+= ${LIBC_SRCTOP}/secure/Symbol.map diff --git a/lib/libc/secure/Symbol.map b/lib/libc/secure/Symbol.map index 1f12fe059367..df0a2d1ac93d 100644 --- a/lib/libc/secure/Symbol.map +++ b/lib/libc/secure/Symbol.map @@ -1,24 +1,25 @@ FBSD_1.0 { __chk_fail; __stack_chk_fail; __stack_chk_guard; }; FBSD_1.8 { __fgets_chk; __memcpy_chk; __memmove_chk; + __mempcpy_chk; __memset_chk; __snprintf_chk; __sprintf_chk; __stpcpy_chk; __stpncpy_chk; __strcat_chk; __strcpy_chk; __strlcat_chk; __strncat_chk; __strlcpy_chk; __strncpy_chk; __vsnprintf_chk; __vsprintf_chk; }; diff --git a/lib/libc/secure/mempcpy_chk.c b/lib/libc/secure/mempcpy_chk.c new file mode 100644 index 000000000000..ca4ae150bc94 --- /dev/null +++ b/lib/libc/secure/mempcpy_chk.c @@ -0,0 +1,49 @@ +/*- + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2006 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. + */ + +#include + +#include +#undef mempcpy + +void * +__mempcpy_chk(void * __restrict dst, const void * __restrict src, size_t len, + size_t slen) +{ + if (len > slen) + __chk_fail(); + + if (__ssp_overlap(src, dst, len)) + __chk_fail(); + + return (mempcpy(dst, src, len)); +} diff --git a/lib/libc/string/mempcpy.c b/lib/libc/string/mempcpy.c index 86e44cdebb85..4ea0af87aef1 100644 --- a/lib/libc/string/mempcpy.c +++ b/lib/libc/string/mempcpy.c @@ -1,39 +1,39 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 The FreeBSD Foundation * * This software was developed by Konstantin Belousov * under sponsorship from the FreeBSD Foundation. * * 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. */ #include #include void * -__ssp_real(mempcpy)(void *__restrict dst, const void *__restrict src, +(mempcpy)(void *__restrict dst, const void *__restrict src, size_t len) { return ((char *)memcpy(dst, src, len) + len); }