diff --git a/include/ssp/Makefile b/include/ssp/Makefile index 2bbbc2eab705..725d82ff10e5 100644 --- a/include/ssp/Makefile +++ b/include/ssp/Makefile @@ -1,4 +1,4 @@ -INCS= poll.h ssp.h stdio.h stdlib.h string.h strings.h unistd.h +INCS= poll.h ssp.h stdio.h stdlib.h string.h strings.h unistd.h wchar.h INCSDIR= ${INCLUDEDIR}/ssp .include diff --git a/include/ssp/wchar.h b/include/ssp/wchar.h new file mode 100644 index 000000000000..48fc56f9d243 --- /dev/null +++ b/include/ssp/wchar.h @@ -0,0 +1,229 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024, Klara, Inc. + * + * 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_WCHAR_H_ +#define _SSP_WCHAR_H_ + +#include + +#if __SSP_FORTIFY_LEVEL > 0 + +static inline int +__ssp_wchar_overlap(const void *leftp, const void *rightp, size_t len) +{ + + if (len > SIZE_MAX / sizeof(wchar_t)) + return (1); + return (__ssp_overlap(leftp, rightp, len * sizeof(wchar_t))); +} + +/* + * __ssp_wbos for w*() calls where the size parameters are in sizeof(wchar_t) + * units, so the result needs to be scaled appropriately. + */ +__ssp_inline size_t +__ssp_wbos(void *ptr) +{ + const size_t ptrsize = __ssp_bos(ptr); + + if (ptrsize == (size_t)-1) + return (ptrsize); + + return (ptrsize / sizeof(wchar_t)); +} + +__BEGIN_DECLS +__ssp_redirect_raw_impl(wchar_t *, wmemcpy, wmemcpy, + (wchar_t *__restrict buf, const wchar_t *__restrict src, size_t len)) +{ + const size_t slen = __ssp_wbos(buf); + + if (len > slen) + __chk_fail(); + if (__ssp_wchar_overlap(src, buf, len)) + __chk_fail(); + + return (__ssp_real(wmemcpy)(buf, src, len)); +} + +__ssp_redirect_raw_impl(wchar_t *, wmempcpy, wmempcpy, + (wchar_t *__restrict buf, const wchar_t *__restrict src, size_t len)) +{ + const size_t slen = __ssp_wbos(buf); + + if (len > slen) + __chk_fail(); + if (__ssp_wchar_overlap(src, buf, len)) + __chk_fail(); + + return (__ssp_real(wmempcpy)(buf, src, len)); +} + +__ssp_redirect_raw_impl(wchar_t *, wmemmove, wmemmove, + (wchar_t *buf, const wchar_t *src, size_t len)) +{ + const size_t slen = __ssp_wbos(buf); + + if (len > slen) + __chk_fail(); + + return (__ssp_real(wmemmove)(buf, src, len)); +} + +__ssp_redirect_raw_impl(wchar_t *, wmemset, wmemset, + (wchar_t *buf, wchar_t c, size_t len)) +{ + const size_t slen = __ssp_wbos(buf); + + if (len > slen) + __chk_fail(); + return (__ssp_real(wmemset)(buf, c, len)); +} + +__ssp_redirect_raw_impl(wchar_t *, wcpcpy, wcpcpy, + (wchar_t *__restrict buf, const wchar_t *__restrict src)) +{ + const size_t slen = __ssp_wbos(buf); + const size_t len = wcslen(src); + + if (len >= slen) + __chk_fail(); + if (__ssp_wchar_overlap(buf, src, len)) + __chk_fail(); + + (void)__ssp_real(wmemcpy)(buf, src, len + 1); + return (buf + len); +} + +__ssp_redirect_raw_impl(wchar_t *, wcpncpy, wcpncpy, + (wchar_t *__restrict buf, const wchar_t *__restrict src, size_t len)) +{ + const size_t slen = __ssp_wbos(buf); + + if (len > slen) + __chk_fail(); + if (__ssp_wchar_overlap(buf, src, len)) + __chk_fail(); + + return (__ssp_real(wcpncpy)(buf, src, len)); +} + +__ssp_redirect_raw_impl(wchar_t *, wcscat, wcscat, + (wchar_t *__restrict buf, const wchar_t *__restrict src)) +{ + size_t slen = __ssp_wbos(buf); + wchar_t *cp; + + cp = buf; + while (*cp != L'\0') { + cp++; + if (slen-- == 0) + __chk_fail(); + } + + while (*src != L'\0') { + if (slen-- == 0) + __chk_fail(); + *cp++ = *src++; + } + + if (slen-- == 0) + __chk_fail(); + *cp = '\0'; + return (buf); +} + +__ssp_redirect_raw_impl(wchar_t *, wcscpy, wcscpy, + (wchar_t *__restrict buf, const wchar_t *__restrict src)) +{ + const size_t slen = __ssp_wbos(buf); + size_t len = wcslen(src) + 1; + + if (len > slen) + __chk_fail(); + if (__ssp_wchar_overlap(buf, src, len)) + __chk_fail(); + + return (__ssp_real(wmemcpy)(buf, src, len)); +} + +__ssp_redirect_raw_impl(wchar_t *, wcsncat, wcsncat, + (wchar_t *__restrict buf, const wchar_t *__restrict src, size_t len)) +{ + const size_t slen = __ssp_wbos(buf); + + if (len == 0) + return (buf); + if (len > slen) + __chk_fail(); + if (__ssp_wchar_overlap(buf, src, len)) + __chk_fail(); + + return (__ssp_real(wcsncat)(buf, src, len)); +} + +__ssp_redirect_raw_impl(size_t, wcslcat, wcslcat, + (wchar_t *__restrict buf, const wchar_t *__restrict src, size_t len)) +{ + const size_t slen = __ssp_wbos(buf); + + if (len > slen) + __chk_fail(); + if (__ssp_wchar_overlap(buf, src, len)) + __chk_fail(); + + return (__ssp_real(wcslcat)(buf, src, len)); +} + +__ssp_redirect_raw_impl(wchar_t *, wcsncpy, wcsncpy, + (wchar_t *__restrict buf, const wchar_t *__restrict src, size_t len)) +{ + const size_t slen = __ssp_wbos(buf); + + if (len > slen) + __chk_fail(); + if (__ssp_wchar_overlap(buf, src, len)) + __chk_fail(); + + return (__ssp_real(wcsncpy)(buf, src, len)); +} + +__ssp_redirect_raw_impl(size_t, wcslcpy, wcslcpy, + (wchar_t *__restrict buf, const wchar_t *__restrict src, size_t len)) +{ + const size_t slen = __ssp_wbos(buf); + + if (len > slen) + __chk_fail(); + if (__ssp_wchar_overlap(buf, src, len)) + __chk_fail(); + + return (__ssp_real(wcslcpy)(buf, src, len)); +} +__END_DECLS + +#endif /* __SSP_FORTIFY_LEVEL > 0 */ +#endif /* _SSP_WCHAR_H_ */ diff --git a/include/wchar.h b/include/wchar.h index 2f23feec8792..e4b037c9b16f 100644 --- a/include/wchar.h +++ b/include/wchar.h @@ -1,242 +1,249 @@ /*- * SPDX-License-Identifier: (BSD-2-Clause) * * Copyright (c)1999 Citrus Project, * 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. */ /*- * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Julian Coleman. * * 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. * * $NetBSD: wchar.h,v 1.8 2000/12/22 05:31:42 itojun Exp $ */ #ifndef _WCHAR_H_ #define _WCHAR_H_ #include #include #include #include #include <_ctype.h> #ifndef _MBSTATE_T_DECLARED typedef __mbstate_t mbstate_t; #define _MBSTATE_T_DECLARED #endif #ifndef _SIZE_T_DECLARED typedef __size_t size_t; #define _SIZE_T_DECLARED #endif #if __POSIX_VISIBLE >= 200809 || __XSI_VISIBLE #ifndef _VA_LIST_DECLARED typedef __va_list va_list; #define _VA_LIST_DECLARED #endif #endif #ifndef __cplusplus #ifndef _WCHAR_T_DECLARED typedef ___wchar_t wchar_t; #define _WCHAR_T_DECLARED #endif #endif #ifndef _WINT_T_DECLARED typedef __wint_t wint_t; #define _WINT_T_DECLARED #endif #define WCHAR_MIN __WCHAR_MIN #define WCHAR_MAX __WCHAR_MAX #ifndef WEOF #define WEOF ((wint_t)-1) #endif #ifndef _STDFILE_DECLARED #define _STDFILE_DECLARED typedef struct __sFILE FILE; #endif struct tm; +__BEGIN_DECLS +size_t wcslen(const wchar_t *) __pure; +__END_DECLS + +#if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 +#include +#endif + __BEGIN_DECLS wint_t btowc(int); wint_t fgetwc(FILE *); wchar_t * fgetws(wchar_t * __restrict, int, FILE * __restrict); wint_t fputwc(wchar_t, FILE *); int fputws(const wchar_t * __restrict, FILE * __restrict); int fwide(FILE *, int); int fwprintf(FILE * __restrict, const wchar_t * __restrict, ...); int fwscanf(FILE * __restrict, const wchar_t * __restrict, ...); wint_t getwc(FILE *); wint_t getwchar(void); size_t mbrlen(const char * __restrict, size_t, mbstate_t * __restrict); size_t mbrtowc(wchar_t * __restrict, const char * __restrict, size_t, mbstate_t * __restrict); int mbsinit(const mbstate_t *); size_t mbsrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, mbstate_t * __restrict); wint_t putwc(wchar_t, FILE *); wint_t putwchar(wchar_t); int swprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict, ...); int swscanf(const wchar_t * __restrict, const wchar_t * __restrict, ...); wint_t ungetwc(wint_t, FILE *); int vfwprintf(FILE * __restrict, const wchar_t * __restrict, __va_list); int vswprintf(wchar_t * __restrict, size_t n, const wchar_t * __restrict, __va_list); int vwprintf(const wchar_t * __restrict, __va_list); size_t wcrtomb(char * __restrict, wchar_t, mbstate_t * __restrict); wchar_t *wcscat(wchar_t * __restrict, const wchar_t * __restrict); wchar_t *wcschr(const wchar_t *, wchar_t) __pure; int wcscmp(const wchar_t *, const wchar_t *) __pure; int wcscoll(const wchar_t *, const wchar_t *); wchar_t *wcscpy(wchar_t * __restrict, const wchar_t * __restrict); size_t wcscspn(const wchar_t *, const wchar_t *) __pure; size_t wcsftime(wchar_t * __restrict, size_t, const wchar_t * __restrict, const struct tm * __restrict); -size_t wcslen(const wchar_t *) __pure; wchar_t *wcsncat(wchar_t * __restrict, const wchar_t * __restrict, size_t); int wcsncmp(const wchar_t *, const wchar_t *, size_t) __pure; wchar_t *wcsncpy(wchar_t * __restrict , const wchar_t * __restrict, size_t); wchar_t *wcspbrk(const wchar_t *, const wchar_t *) __pure; wchar_t *wcsrchr(const wchar_t *, wchar_t) __pure; size_t wcsrtombs(char * __restrict, const wchar_t ** __restrict, size_t, mbstate_t * __restrict); size_t wcsspn(const wchar_t *, const wchar_t *) __pure; wchar_t *wcsstr(const wchar_t * __restrict, const wchar_t * __restrict) __pure; size_t wcsxfrm(wchar_t * __restrict, const wchar_t * __restrict, size_t); int wctob(wint_t); double wcstod(const wchar_t * __restrict, wchar_t ** __restrict); wchar_t *wcstok(wchar_t * __restrict, const wchar_t * __restrict, wchar_t ** __restrict); long wcstol(const wchar_t * __restrict, wchar_t ** __restrict, int); unsigned long wcstoul(const wchar_t * __restrict, wchar_t ** __restrict, int); wchar_t *wmemchr(const wchar_t *, wchar_t, size_t) __pure; int wmemcmp(const wchar_t *, const wchar_t *, size_t) __pure; wchar_t *wmemcpy(wchar_t * __restrict, const wchar_t * __restrict, size_t); wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t); #if __BSD_VISIBLE wchar_t *wmempcpy(wchar_t * __restrict, const wchar_t * __restrict, size_t); #endif wchar_t *wmemset(wchar_t *, wchar_t, size_t); int wprintf(const wchar_t * __restrict, ...); int wscanf(const wchar_t * __restrict, ...); #ifndef _STDSTREAM_DECLARED extern FILE *__stdinp; extern FILE *__stdoutp; extern FILE *__stderrp; #define _STDSTREAM_DECLARED #endif #define getwc(fp) fgetwc(fp) #define getwchar() fgetwc(__stdinp) #define putwc(wc, fp) fputwc(wc, fp) #define putwchar(wc) fputwc(wc, __stdoutp) #if __ISO_C_VISIBLE >= 1999 int vfwscanf(FILE * __restrict, const wchar_t * __restrict, __va_list); int vswscanf(const wchar_t * __restrict, const wchar_t * __restrict, __va_list); int vwscanf(const wchar_t * __restrict, __va_list); float wcstof(const wchar_t * __restrict, wchar_t ** __restrict); long double wcstold(const wchar_t * __restrict, wchar_t ** __restrict); #ifdef __LONG_LONG_SUPPORTED /* LONGLONG */ long long wcstoll(const wchar_t * __restrict, wchar_t ** __restrict, int); /* LONGLONG */ unsigned long long wcstoull(const wchar_t * __restrict, wchar_t ** __restrict, int); #endif #endif /* __ISO_C_VISIBLE >= 1999 */ #if __XSI_VISIBLE int wcswidth(const wchar_t *, size_t); int wcwidth(wchar_t); #define wcwidth(_c) __wcwidth(_c) #endif #if __POSIX_VISIBLE >= 200809 size_t mbsnrtowcs(wchar_t * __restrict, const char ** __restrict, size_t, size_t, mbstate_t * __restrict); FILE *open_wmemstream(wchar_t **, size_t *); wchar_t *wcpcpy(wchar_t * __restrict, const wchar_t * __restrict); wchar_t *wcpncpy(wchar_t * __restrict, const wchar_t * __restrict, size_t); wchar_t *wcsdup(const wchar_t *) __malloc_like; int wcscasecmp(const wchar_t *, const wchar_t *); int wcsncasecmp(const wchar_t *, const wchar_t *, size_t n); size_t wcsnlen(const wchar_t *, size_t) __pure; size_t wcsnrtombs(char * __restrict, const wchar_t ** __restrict, size_t, size_t, mbstate_t * __restrict); #endif #if __BSD_VISIBLE wchar_t *fgetwln(FILE * __restrict, size_t * __restrict); size_t wcslcat(wchar_t *, const wchar_t *, size_t); size_t wcslcpy(wchar_t *, const wchar_t *, size_t); #endif #if __POSIX_VISIBLE >= 200809 || defined(_XLOCALE_H_) #include #endif __END_DECLS #endif /* !_WCHAR_H_ */ diff --git a/lib/libc/string/wcpcpy.c b/lib/libc/string/wcpcpy.c index 2d377dab2777..2ae014b31d29 100644 --- a/lib/libc/string/wcpcpy.c +++ b/lib/libc/string/wcpcpy.c @@ -1,42 +1,43 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1999 * David E. O'Brien * Copyright (c) 1988, 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. */ #include +#include wchar_t * -wcpcpy(wchar_t * __restrict to, const wchar_t * __restrict from) +__ssp_real(wcpcpy)(wchar_t * __restrict to, const wchar_t * __restrict from) { for (; (*to = *from); ++from, ++to); return(to); } diff --git a/lib/libc/string/wcpncpy.c b/lib/libc/string/wcpncpy.c index 72c060842e26..e89facfeb642 100644 --- a/lib/libc/string/wcpncpy.c +++ b/lib/libc/string/wcpncpy.c @@ -1,44 +1,46 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2009 David Schultz * 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. */ #include +#include wchar_t * -wcpncpy(wchar_t * __restrict dst, const wchar_t * __restrict src, size_t n) +__ssp_real(wcpncpy)(wchar_t * __restrict dst, const wchar_t * __restrict src, + size_t n) { for (; n--; dst++, src++) { if (!(*dst = *src)) { wchar_t *ret = dst; while (n--) *++dst = L'\0'; return (ret); } } return (dst); } diff --git a/lib/libc/string/wcscat.c b/lib/libc/string/wcscat.c index 3599e562e9b4..98e088100a87 100644 --- a/lib/libc/string/wcscat.c +++ b/lib/libc/string/wcscat.c @@ -1,51 +1,52 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c)1999 Citrus Project, * 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. * * citrus Id: wcscat.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: wcscat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif #include +#include wchar_t * -wcscat(wchar_t * __restrict s1, const wchar_t * __restrict s2) +__ssp_real(wcscat)(wchar_t * __restrict s1, const wchar_t * __restrict s2) { wchar_t *cp; cp = s1; while (*cp != L'\0') cp++; while ((*cp++ = *s2++) != L'\0') ; return (s1); } diff --git a/lib/libc/string/wcscpy.c b/lib/libc/string/wcscpy.c index 622e4201f84b..d4aed8721bb8 100644 --- a/lib/libc/string/wcscpy.c +++ b/lib/libc/string/wcscpy.c @@ -1,49 +1,50 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c)1999 Citrus Project, * 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. * * citrus Id: wcscpy.c,v 1.2 2000/12/21 04:51:09 itojun Exp */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: wcscpy.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif #include +#include wchar_t * -wcscpy(wchar_t * __restrict s1, const wchar_t * __restrict s2) +__ssp_real(wcscpy)(wchar_t * __restrict s1, const wchar_t * __restrict s2) { wchar_t *cp; cp = s1; while ((*cp++ = *s2++) != L'\0') ; return (s1); } diff --git a/lib/libc/string/wcslcat.c b/lib/libc/string/wcslcat.c index 336947e3cd23..f74ce520b6a7 100644 --- a/lib/libc/string/wcslcat.c +++ b/lib/libc/string/wcslcat.c @@ -1,74 +1,75 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1998 Todd C. Miller * 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. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``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 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. * * from OpenBSD: strlcat.c,v 1.3 2000/11/24 11:10:02 itojun Exp */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: wcslcat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif #include #include +#include /* * Appends src to string dst of size siz (unlike wcsncat, siz is the * full size of dst, not space left). At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns wcslen(initial dst) + wcslen(src); if retval >= siz, * truncation occurred. */ size_t -wcslcat(wchar_t *dst, const wchar_t *src, size_t siz) +__ssp_real(wcslcat)(wchar_t *dst, const wchar_t *src, size_t siz) { wchar_t *d = dst; const wchar_t *s = src; size_t n = siz; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */ while (n-- != 0 && *d != '\0') d++; dlen = d - dst; n = siz - dlen; if (n == 0) return(dlen + wcslen(s)); while (*s != '\0') { if (n != 1) { *d++ = *s; n--; } s++; } *d = '\0'; return(dlen + (s - src)); /* count does not include NUL */ } diff --git a/lib/libc/string/wcslcpy.c b/lib/libc/string/wcslcpy.c index 920425bb5efc..82269656b985 100644 --- a/lib/libc/string/wcslcpy.c +++ b/lib/libc/string/wcslcpy.c @@ -1,70 +1,71 @@ /* * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1998 Todd C. Miller * 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. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``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 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. * * from OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: wcslcpy.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif #include #include +#include /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns wcslen(src); if retval >= siz, truncation occurred. */ size_t -wcslcpy(wchar_t *dst, const wchar_t *src, size_t siz) +__ssp_real(wcslcpy)(wchar_t *dst, const wchar_t *src, size_t siz) { wchar_t *d = dst; const wchar_t *s = src; size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0 && --n != 0) { do { if ((*d++ = *s++) == 0) break; } while (--n != 0); } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ } diff --git a/lib/libc/string/wcsncat.c b/lib/libc/string/wcsncat.c index 004391423f53..5b36fd40bb4f 100644 --- a/lib/libc/string/wcsncat.c +++ b/lib/libc/string/wcsncat.c @@ -1,57 +1,59 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c)1999 Citrus Project, * 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. * * citrus Id: wcsncat.c,v 1.1 1999/12/29 21:47:45 tshiozak Exp */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: wcsncat.c,v 1.1 2000/12/23 23:14:36 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif #include +#include wchar_t * -wcsncat(wchar_t * __restrict s1, const wchar_t * __restrict s2, size_t n) +__ssp_real(wcsncat)(wchar_t * __restrict s1, const wchar_t * __restrict s2, + size_t n) { wchar_t *p; wchar_t *q; const wchar_t *r; p = s1; while (*p) p++; q = p; r = s2; while (n && *r) { *q++ = *r++; n--; } *q = '\0'; return s1; } diff --git a/lib/libc/string/wcsncpy.c b/lib/libc/string/wcsncpy.c index a02a8292c0d1..2491dadadfa4 100644 --- a/lib/libc/string/wcsncpy.c +++ b/lib/libc/string/wcsncpy.c @@ -1,58 +1,60 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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. */ #include +#include /* * Copy src to dst, truncating or null-padding to always copy n bytes. * Return dst. */ wchar_t * -wcsncpy(wchar_t * __restrict dst, const wchar_t * __restrict src, size_t n) +__ssp_real(wcsncpy)(wchar_t * __restrict dst, const wchar_t * __restrict src, + size_t n) { if (n != 0) { wchar_t *d = dst; const wchar_t *s = src; do { if ((*d++ = *s++) == L'\0') { /* NUL pad the remaining n-1 bytes */ while (--n != 0) *d++ = L'\0'; break; } } while (--n != 0); } return (dst); } diff --git a/lib/libc/string/wmemcpy.c b/lib/libc/string/wmemcpy.c index f692a25fc95b..9db16fe77a69 100644 --- a/lib/libc/string/wmemcpy.c +++ b/lib/libc/string/wmemcpy.c @@ -1,44 +1,46 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c)1999 Citrus Project, * 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. * * citrus Id: wmemcpy.c,v 1.2 2000/12/20 14:08:31 itojun Exp */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: wmemcpy.c,v 1.1 2000/12/23 23:14:37 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif #include #include +#include wchar_t * -wmemcpy(wchar_t * __restrict d, const wchar_t * __restrict s, size_t n) +__ssp_real(wmemcpy)(wchar_t * __restrict d, const wchar_t * __restrict s, + size_t n) { return (wchar_t *)memcpy(d, s, n * sizeof(wchar_t)); } diff --git a/lib/libc/string/wmemmove.c b/lib/libc/string/wmemmove.c index cbbdb4afdd6c..837dbe12dc7a 100644 --- a/lib/libc/string/wmemmove.c +++ b/lib/libc/string/wmemmove.c @@ -1,44 +1,45 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c)1999 Citrus Project, * 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. * * citrus Id: wmemmove.c,v 1.2 2000/12/20 14:08:31 itojun Exp */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: wmemmove.c,v 1.1 2000/12/23 23:14:37 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif #include #include +#include wchar_t * -wmemmove(wchar_t *d, const wchar_t *s, size_t n) +__ssp_real(wmemmove)(wchar_t *d, const wchar_t *s, size_t n) { return (wchar_t *)memmove(d, s, n * sizeof(wchar_t)); } diff --git a/lib/libc/string/wmempcpy.c b/lib/libc/string/wmempcpy.c index 6551787abf65..152bb76c7e80 100644 --- a/lib/libc/string/wmempcpy.c +++ b/lib/libc/string/wmempcpy.c @@ -1,38 +1,40 @@ /*- * 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 +#include wchar_t * -wmempcpy(wchar_t *__restrict dst, const wchar_t *__restrict src, size_t len) +__ssp_real(wmempcpy)(wchar_t *__restrict dst, const wchar_t *__restrict src, + size_t len) { return (wmemcpy(dst, src, len) + len); } diff --git a/lib/libc/string/wmemset.c b/lib/libc/string/wmemset.c index 4276373399f9..60fb14b6a4af 100644 --- a/lib/libc/string/wmemset.c +++ b/lib/libc/string/wmemset.c @@ -1,51 +1,52 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c)1999 Citrus Project, * 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. * * citrus Id: wmemset.c,v 1.2 2000/12/20 14:08:31 itojun Exp */ #include #if 0 #if defined(LIBC_SCCS) && !defined(lint) __RCSID("$NetBSD: wmemset.c,v 1.1 2000/12/23 23:14:37 itojun Exp $"); #endif /* LIBC_SCCS and not lint */ #endif #include +#include wchar_t * -wmemset(wchar_t *s, wchar_t c, size_t n) +__ssp_real(wmemset)(wchar_t *s, wchar_t c, size_t n) { size_t i; wchar_t *p; p = (wchar_t *)s; for (i = 0; i < n; i++) { *p = c; p++; } return s; } diff --git a/lib/libc/tests/secure/Makefile b/lib/libc/tests/secure/Makefile index 63fe4cb96f02..27d29eabe689 100644 --- a/lib/libc/tests/secure/Makefile +++ b/lib/libc/tests/secure/Makefile @@ -1,22 +1,23 @@ .include TESTSDIR:= ${TESTSBASE}/${RELDIR:C/libc\/tests/libc/} FORTIFY_TCATS+= poll FORTIFY_TCATS+= stdlib FORTIFY_TCATS+= stdio FORTIFY_TCATS+= string FORTIFY_TCATS+= strings FORTIFY_TCATS+= unistd +FORTIFY_TCATS+= wchar # Manually run after updating the test generator. generate-tests: .PHONY .for tcat in ${FORTIFY_TCATS} ATF_TESTS_C+= fortify_${tcat}_test generate-tests: generate-tests-${tcat} generate-tests-${tcat}: .PHONY ${.CURDIR}/generate-fortify-tests.lua ${tcat} > ${.CURDIR}/fortify_${tcat}_test.c .endfor .include diff --git a/lib/libc/tests/secure/fortify_poll_test.c b/lib/libc/tests/secure/fortify_poll_test.c index 9d9cb4ace35a..447ff400dc05 100644 --- a/lib/libc/tests/secure/fortify_poll_test.c +++ b/lib/libc/tests/secure/fortify_poll_test.c @@ -1,531 +1,532 @@ /* @generated by `generate-fortify-tests.lua "poll"` */ #define _FORTIFY_SOURCE 2 #define TMPFILE_SIZE (1024 * 32) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include static FILE * __unused new_fp(size_t __len) { static char fpbuf[LINE_MAX]; FILE *fp; ATF_REQUIRE(__len <= sizeof(fpbuf)); memset(fpbuf, 'A', sizeof(fpbuf) - 1); fpbuf[sizeof(fpbuf) - 1] = '\0'; fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); ATF_REQUIRE(fp != NULL); return (fp); } /* * Create a new symlink to use for readlink(2) style tests, we'll just use a * random target name to have something interesting to look at. */ static const char * __unused new_symlink(size_t __len) { static const char linkname[] = "link"; char target[MAXNAMLEN]; int error; ATF_REQUIRE(__len <= sizeof(target)); arc4random_buf(target, sizeof(target)); error = unlink(linkname); ATF_REQUIRE(error == 0 || errno == ENOENT); error = symlink(target, linkname); ATF_REQUIRE(error == 0); return (linkname); } /* * Constructs a tmpfile that we can use for testing read(2) and friends. */ static int __unused new_tmpfile(void) { char buf[1024]; ssize_t rv; size_t written; int fd; fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); ATF_REQUIRE(fd >= 0); written = 0; while (written < TMPFILE_SIZE) { rv = write(fd, buf, sizeof(buf)); ATF_REQUIRE(rv > 0); written += rv; } ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); return (fd); } static void disable_coredumps(void) { struct rlimit rl = { 0 }; if (setrlimit(RLIMIT_CORE, &rl) == -1) _exit(EX_OSERR); } /* * Replaces stdin with a file that we can actually read from, for tests where * we want a FILE * or fd that we can get data from. */ static void __unused replace_stdin(void) { int fd; fd = new_tmpfile(); (void)dup2(fd, STDIN_FILENO); if (fd != STDIN_FILENO) close(fd); } ATF_TC_WITHOUT_HEAD(poll_before_end); ATF_TC_BODY(poll_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; struct pollfd __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } poll(__stack.__buf, __len, 0); #undef BUF } ATF_TC_WITHOUT_HEAD(poll_end); ATF_TC_BODY(poll_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; struct pollfd __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4; const size_t __idx __unused = __len - 1; for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } poll(__stack.__buf, __len, 0); #undef BUF } ATF_TC_WITHOUT_HEAD(poll_after_end); ATF_TC_BODY(poll_after_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; struct pollfd __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } poll(__stack.__buf, __len, 0); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(poll_heap_before_end); ATF_TC_BODY(poll_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; struct pollfd * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } poll(__stack.__buf, __len, 0); #undef BUF } ATF_TC_WITHOUT_HEAD(poll_heap_end); ATF_TC_BODY(poll_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; struct pollfd * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } poll(__stack.__buf, __len, 0); #undef BUF } ATF_TC_WITHOUT_HEAD(poll_heap_after_end); ATF_TC_BODY(poll_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; struct pollfd * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } poll(__stack.__buf, __len, 0); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(ppoll_before_end); ATF_TC_BODY(ppoll_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; struct pollfd __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; struct timespec tv = { 0 }; for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } ppoll(__stack.__buf, __len, &tv, NULL); #undef BUF } ATF_TC_WITHOUT_HEAD(ppoll_end); ATF_TC_BODY(ppoll_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; struct pollfd __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4; const size_t __idx __unused = __len - 1; struct timespec tv = { 0 }; for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } ppoll(__stack.__buf, __len, &tv, NULL); #undef BUF } ATF_TC_WITHOUT_HEAD(ppoll_after_end); ATF_TC_BODY(ppoll_after_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; struct pollfd __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; struct timespec tv = { 0 }; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } ppoll(__stack.__buf, __len, &tv, NULL); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(ppoll_heap_before_end); ATF_TC_BODY(ppoll_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; struct pollfd * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; struct timespec tv = { 0 }; __stack.__buf = malloc(__bufsz); for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } ppoll(__stack.__buf, __len, &tv, NULL); #undef BUF } ATF_TC_WITHOUT_HEAD(ppoll_heap_end); ATF_TC_BODY(ppoll_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; struct pollfd * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4; const size_t __idx __unused = __len - 1; struct timespec tv = { 0 }; __stack.__buf = malloc(__bufsz); for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } ppoll(__stack.__buf, __len, &tv, NULL); #undef BUF } ATF_TC_WITHOUT_HEAD(ppoll_heap_after_end); ATF_TC_BODY(ppoll_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; struct pollfd * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; struct timespec tv = { 0 }; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } ppoll(__stack.__buf, __len, &tv, NULL); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, poll_before_end); ATF_TP_ADD_TC(tp, poll_end); ATF_TP_ADD_TC(tp, poll_after_end); ATF_TP_ADD_TC(tp, poll_heap_before_end); ATF_TP_ADD_TC(tp, poll_heap_end); ATF_TP_ADD_TC(tp, poll_heap_after_end); ATF_TP_ADD_TC(tp, ppoll_before_end); ATF_TP_ADD_TC(tp, ppoll_end); ATF_TP_ADD_TC(tp, ppoll_after_end); ATF_TP_ADD_TC(tp, ppoll_heap_before_end); ATF_TP_ADD_TC(tp, ppoll_heap_end); ATF_TP_ADD_TC(tp, ppoll_heap_after_end); return (atf_no_error()); } diff --git a/lib/libc/tests/secure/fortify_stdio_test.c b/lib/libc/tests/secure/fortify_stdio_test.c index 035d84b316e6..f399a32f3ca2 100644 --- a/lib/libc/tests/secure/fortify_stdio_test.c +++ b/lib/libc/tests/secure/fortify_stdio_test.c @@ -1,1374 +1,1375 @@ /* @generated by `generate-fortify-tests.lua "stdio"` */ #define _FORTIFY_SOURCE 2 #define TMPFILE_SIZE (1024 * 32) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include static FILE * __unused new_fp(size_t __len) { static char fpbuf[LINE_MAX]; FILE *fp; ATF_REQUIRE(__len <= sizeof(fpbuf)); memset(fpbuf, 'A', sizeof(fpbuf) - 1); fpbuf[sizeof(fpbuf) - 1] = '\0'; fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); ATF_REQUIRE(fp != NULL); return (fp); } /* * Create a new symlink to use for readlink(2) style tests, we'll just use a * random target name to have something interesting to look at. */ static const char * __unused new_symlink(size_t __len) { static const char linkname[] = "link"; char target[MAXNAMLEN]; int error; ATF_REQUIRE(__len <= sizeof(target)); arc4random_buf(target, sizeof(target)); error = unlink(linkname); ATF_REQUIRE(error == 0 || errno == ENOENT); error = symlink(target, linkname); ATF_REQUIRE(error == 0); return (linkname); } /* * Constructs a tmpfile that we can use for testing read(2) and friends. */ static int __unused new_tmpfile(void) { char buf[1024]; ssize_t rv; size_t written; int fd; fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); ATF_REQUIRE(fd >= 0); written = 0; while (written < TMPFILE_SIZE) { rv = write(fd, buf, sizeof(buf)); ATF_REQUIRE(rv > 0); written += rv; } ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); return (fd); } static void disable_coredumps(void) { struct rlimit rl = { 0 }; if (setrlimit(RLIMIT_CORE, &rl) == -1) _exit(EX_OSERR); } /* * Replaces stdin with a file that we can actually read from, for tests where * we want a FILE * or fd that we can get data from. */ static void __unused replace_stdin(void) { int fd; fd = new_tmpfile(); (void)dup2(fd, STDIN_FILENO); if (fd != STDIN_FILENO) close(fd); } ATF_TC_WITHOUT_HEAD(ctermid_before_end); ATF_TC_BODY(ctermid_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[L_ctermid + 1]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = L_ctermid + 1; const size_t __idx __unused = __len - 1; ctermid(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(ctermid_end); ATF_TC_BODY(ctermid_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[L_ctermid]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = L_ctermid; const size_t __idx __unused = __len - 1; ctermid(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(ctermid_heap_before_end); ATF_TC_BODY(ctermid_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (L_ctermid + 1); const size_t __len = L_ctermid + 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); ctermid(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(ctermid_heap_end); ATF_TC_BODY(ctermid_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (L_ctermid); const size_t __len = L_ctermid; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); ctermid(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(ctermid_heap_after_end); ATF_TC_BODY(ctermid_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (L_ctermid - 1); const size_t __len = L_ctermid - 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); ctermid(__stack.__buf); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(ctermid_r_before_end); ATF_TC_BODY(ctermid_r_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[L_ctermid + 1]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = L_ctermid + 1; const size_t __idx __unused = __len - 1; ctermid_r(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(ctermid_r_end); ATF_TC_BODY(ctermid_r_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[L_ctermid]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = L_ctermid; const size_t __idx __unused = __len - 1; ctermid_r(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(ctermid_r_heap_before_end); ATF_TC_BODY(ctermid_r_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (L_ctermid + 1); const size_t __len = L_ctermid + 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); ctermid_r(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(ctermid_r_heap_end); ATF_TC_BODY(ctermid_r_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (L_ctermid); const size_t __len = L_ctermid; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); ctermid_r(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(ctermid_r_heap_after_end); ATF_TC_BODY(ctermid_r_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (L_ctermid - 1); const size_t __len = L_ctermid - 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); ctermid_r(__stack.__buf); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(fread_before_end); ATF_TC_BODY(fread_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; replace_stdin(); fread(__stack.__buf, __len, 1, stdin); #undef BUF } ATF_TC_WITHOUT_HEAD(fread_end); ATF_TC_BODY(fread_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; replace_stdin(); fread(__stack.__buf, __len, 1, stdin); #undef BUF } ATF_TC_WITHOUT_HEAD(fread_heap_before_end); ATF_TC_BODY(fread_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); replace_stdin(); fread(__stack.__buf, __len, 1, stdin); #undef BUF } ATF_TC_WITHOUT_HEAD(fread_heap_end); ATF_TC_BODY(fread_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); replace_stdin(); fread(__stack.__buf, __len, 1, stdin); #undef BUF } ATF_TC_WITHOUT_HEAD(fread_heap_after_end); ATF_TC_BODY(fread_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); replace_stdin(); fread(__stack.__buf, __len, 1, stdin); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(fread_unlocked_before_end); ATF_TC_BODY(fread_unlocked_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; replace_stdin(); fread_unlocked(__stack.__buf, __len, 1, stdin); #undef BUF } ATF_TC_WITHOUT_HEAD(fread_unlocked_end); ATF_TC_BODY(fread_unlocked_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; replace_stdin(); fread_unlocked(__stack.__buf, __len, 1, stdin); #undef BUF } ATF_TC_WITHOUT_HEAD(fread_unlocked_heap_before_end); ATF_TC_BODY(fread_unlocked_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); replace_stdin(); fread_unlocked(__stack.__buf, __len, 1, stdin); #undef BUF } ATF_TC_WITHOUT_HEAD(fread_unlocked_heap_end); ATF_TC_BODY(fread_unlocked_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); replace_stdin(); fread_unlocked(__stack.__buf, __len, 1, stdin); #undef BUF } ATF_TC_WITHOUT_HEAD(fread_unlocked_heap_after_end); ATF_TC_BODY(fread_unlocked_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); replace_stdin(); fread_unlocked(__stack.__buf, __len, 1, stdin); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(gets_s_before_end); ATF_TC_BODY(gets_s_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; replace_stdin(); gets_s(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(gets_s_end); ATF_TC_BODY(gets_s_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; replace_stdin(); gets_s(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(gets_s_heap_before_end); ATF_TC_BODY(gets_s_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); replace_stdin(); gets_s(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(gets_s_heap_end); ATF_TC_BODY(gets_s_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); replace_stdin(); gets_s(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(gets_s_heap_after_end); ATF_TC_BODY(gets_s_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); replace_stdin(); gets_s(__stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(sprintf_before_end); ATF_TC_BODY(sprintf_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char srcvar[__len + 10]; memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; sprintf(__stack.__buf, "%.*s", (int)__len - 1, srcvar); #undef BUF } ATF_TC_WITHOUT_HEAD(sprintf_end); ATF_TC_BODY(sprintf_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char srcvar[__len + 10]; memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; sprintf(__stack.__buf, "%.*s", (int)__len - 1, srcvar); #undef BUF } ATF_TC_WITHOUT_HEAD(sprintf_heap_before_end); ATF_TC_BODY(sprintf_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char srcvar[__len + 10]; __stack.__buf = malloc(__bufsz); memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; sprintf(__stack.__buf, "%.*s", (int)__len - 1, srcvar); #undef BUF } ATF_TC_WITHOUT_HEAD(sprintf_heap_end); ATF_TC_BODY(sprintf_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char srcvar[__len + 10]; __stack.__buf = malloc(__bufsz); memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; sprintf(__stack.__buf, "%.*s", (int)__len - 1, srcvar); #undef BUF } ATF_TC_WITHOUT_HEAD(sprintf_heap_after_end); ATF_TC_BODY(sprintf_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char srcvar[__len + 10]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; sprintf(__stack.__buf, "%.*s", (int)__len - 1, srcvar); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(snprintf_before_end); ATF_TC_BODY(snprintf_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char srcvar[__len + 10]; memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; snprintf(__stack.__buf, __len, "%.*s", (int)__len - 1, srcvar); #undef BUF } ATF_TC_WITHOUT_HEAD(snprintf_end); ATF_TC_BODY(snprintf_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char srcvar[__len + 10]; memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; snprintf(__stack.__buf, __len, "%.*s", (int)__len - 1, srcvar); #undef BUF } ATF_TC_WITHOUT_HEAD(snprintf_heap_before_end); ATF_TC_BODY(snprintf_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char srcvar[__len + 10]; __stack.__buf = malloc(__bufsz); memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; snprintf(__stack.__buf, __len, "%.*s", (int)__len - 1, srcvar); #undef BUF } ATF_TC_WITHOUT_HEAD(snprintf_heap_end); ATF_TC_BODY(snprintf_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char srcvar[__len + 10]; __stack.__buf = malloc(__bufsz); memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; snprintf(__stack.__buf, __len, "%.*s", (int)__len - 1, srcvar); #undef BUF } ATF_TC_WITHOUT_HEAD(snprintf_heap_after_end); ATF_TC_BODY(snprintf_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char srcvar[__len + 10]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; snprintf(__stack.__buf, __len, "%.*s", (int)__len - 1, srcvar); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(tmpnam_before_end); ATF_TC_BODY(tmpnam_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[L_tmpnam + 1]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = L_tmpnam + 1; const size_t __idx __unused = __len - 1; tmpnam(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(tmpnam_end); ATF_TC_BODY(tmpnam_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[L_tmpnam]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = L_tmpnam; const size_t __idx __unused = __len - 1; tmpnam(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(tmpnam_heap_before_end); ATF_TC_BODY(tmpnam_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (L_tmpnam + 1); const size_t __len = L_tmpnam + 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); tmpnam(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(tmpnam_heap_end); ATF_TC_BODY(tmpnam_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (L_tmpnam); const size_t __len = L_tmpnam; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); tmpnam(__stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(tmpnam_heap_after_end); ATF_TC_BODY(tmpnam_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (L_tmpnam - 1); const size_t __len = L_tmpnam - 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); tmpnam(__stack.__buf); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(fgets_before_end); ATF_TC_BODY(fgets_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; FILE *fp; fp = new_fp(__len); fgets(__stack.__buf, __len, fp); #undef BUF } ATF_TC_WITHOUT_HEAD(fgets_end); ATF_TC_BODY(fgets_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; FILE *fp; fp = new_fp(__len); fgets(__stack.__buf, __len, fp); #undef BUF } ATF_TC_WITHOUT_HEAD(fgets_heap_before_end); ATF_TC_BODY(fgets_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; FILE *fp; __stack.__buf = malloc(__bufsz); fp = new_fp(__len); fgets(__stack.__buf, __len, fp); #undef BUF } ATF_TC_WITHOUT_HEAD(fgets_heap_end); ATF_TC_BODY(fgets_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; FILE *fp; __stack.__buf = malloc(__bufsz); fp = new_fp(__len); fgets(__stack.__buf, __len, fp); #undef BUF } ATF_TC_WITHOUT_HEAD(fgets_heap_after_end); ATF_TC_BODY(fgets_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; FILE *fp; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); fp = new_fp(__len); fgets(__stack.__buf, __len, fp); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, ctermid_before_end); ATF_TP_ADD_TC(tp, ctermid_end); ATF_TP_ADD_TC(tp, ctermid_heap_before_end); ATF_TP_ADD_TC(tp, ctermid_heap_end); ATF_TP_ADD_TC(tp, ctermid_heap_after_end); ATF_TP_ADD_TC(tp, ctermid_r_before_end); ATF_TP_ADD_TC(tp, ctermid_r_end); ATF_TP_ADD_TC(tp, ctermid_r_heap_before_end); ATF_TP_ADD_TC(tp, ctermid_r_heap_end); ATF_TP_ADD_TC(tp, ctermid_r_heap_after_end); ATF_TP_ADD_TC(tp, fread_before_end); ATF_TP_ADD_TC(tp, fread_end); ATF_TP_ADD_TC(tp, fread_heap_before_end); ATF_TP_ADD_TC(tp, fread_heap_end); ATF_TP_ADD_TC(tp, fread_heap_after_end); ATF_TP_ADD_TC(tp, fread_unlocked_before_end); ATF_TP_ADD_TC(tp, fread_unlocked_end); ATF_TP_ADD_TC(tp, fread_unlocked_heap_before_end); ATF_TP_ADD_TC(tp, fread_unlocked_heap_end); ATF_TP_ADD_TC(tp, fread_unlocked_heap_after_end); ATF_TP_ADD_TC(tp, gets_s_before_end); ATF_TP_ADD_TC(tp, gets_s_end); ATF_TP_ADD_TC(tp, gets_s_heap_before_end); ATF_TP_ADD_TC(tp, gets_s_heap_end); ATF_TP_ADD_TC(tp, gets_s_heap_after_end); ATF_TP_ADD_TC(tp, sprintf_before_end); ATF_TP_ADD_TC(tp, sprintf_end); ATF_TP_ADD_TC(tp, sprintf_heap_before_end); ATF_TP_ADD_TC(tp, sprintf_heap_end); ATF_TP_ADD_TC(tp, sprintf_heap_after_end); ATF_TP_ADD_TC(tp, snprintf_before_end); ATF_TP_ADD_TC(tp, snprintf_end); ATF_TP_ADD_TC(tp, snprintf_heap_before_end); ATF_TP_ADD_TC(tp, snprintf_heap_end); ATF_TP_ADD_TC(tp, snprintf_heap_after_end); ATF_TP_ADD_TC(tp, tmpnam_before_end); ATF_TP_ADD_TC(tp, tmpnam_end); ATF_TP_ADD_TC(tp, tmpnam_heap_before_end); ATF_TP_ADD_TC(tp, tmpnam_heap_end); ATF_TP_ADD_TC(tp, tmpnam_heap_after_end); ATF_TP_ADD_TC(tp, fgets_before_end); ATF_TP_ADD_TC(tp, fgets_end); ATF_TP_ADD_TC(tp, fgets_heap_before_end); ATF_TP_ADD_TC(tp, fgets_heap_end); ATF_TP_ADD_TC(tp, fgets_heap_after_end); return (atf_no_error()); } diff --git a/lib/libc/tests/secure/fortify_stdlib_test.c b/lib/libc/tests/secure/fortify_stdlib_test.c index e00983a58aa4..87e6b4b86302 100644 --- a/lib/libc/tests/secure/fortify_stdlib_test.c +++ b/lib/libc/tests/secure/fortify_stdlib_test.c @@ -1,383 +1,384 @@ /* @generated by `generate-fortify-tests.lua "stdlib"` */ #define _FORTIFY_SOURCE 2 #define TMPFILE_SIZE (1024 * 32) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include static FILE * __unused new_fp(size_t __len) { static char fpbuf[LINE_MAX]; FILE *fp; ATF_REQUIRE(__len <= sizeof(fpbuf)); memset(fpbuf, 'A', sizeof(fpbuf) - 1); fpbuf[sizeof(fpbuf) - 1] = '\0'; fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); ATF_REQUIRE(fp != NULL); return (fp); } /* * Create a new symlink to use for readlink(2) style tests, we'll just use a * random target name to have something interesting to look at. */ static const char * __unused new_symlink(size_t __len) { static const char linkname[] = "link"; char target[MAXNAMLEN]; int error; ATF_REQUIRE(__len <= sizeof(target)); arc4random_buf(target, sizeof(target)); error = unlink(linkname); ATF_REQUIRE(error == 0 || errno == ENOENT); error = symlink(target, linkname); ATF_REQUIRE(error == 0); return (linkname); } /* * Constructs a tmpfile that we can use for testing read(2) and friends. */ static int __unused new_tmpfile(void) { char buf[1024]; ssize_t rv; size_t written; int fd; fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); ATF_REQUIRE(fd >= 0); written = 0; while (written < TMPFILE_SIZE) { rv = write(fd, buf, sizeof(buf)); ATF_REQUIRE(rv > 0); written += rv; } ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); return (fd); } static void disable_coredumps(void) { struct rlimit rl = { 0 }; if (setrlimit(RLIMIT_CORE, &rl) == -1) _exit(EX_OSERR); } /* * Replaces stdin with a file that we can actually read from, for tests where * we want a FILE * or fd that we can get data from. */ static void __unused replace_stdin(void) { int fd; fd = new_tmpfile(); (void)dup2(fd, STDIN_FILENO); if (fd != STDIN_FILENO) close(fd); } ATF_TC_WITHOUT_HEAD(arc4random_buf_before_end); ATF_TC_BODY(arc4random_buf_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; arc4random_buf(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(arc4random_buf_end); ATF_TC_BODY(arc4random_buf_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; arc4random_buf(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(arc4random_buf_heap_before_end); ATF_TC_BODY(arc4random_buf_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); arc4random_buf(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(arc4random_buf_heap_end); ATF_TC_BODY(arc4random_buf_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); arc4random_buf(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(arc4random_buf_heap_after_end); ATF_TC_BODY(arc4random_buf_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); arc4random_buf(__stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(realpath_before_end); ATF_TC_BODY(realpath_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[PATH_MAX + 1]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = PATH_MAX + 1; const size_t __idx __unused = __len - 1; realpath(".", __stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(realpath_end); ATF_TC_BODY(realpath_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[PATH_MAX]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = PATH_MAX; const size_t __idx __unused = __len - 1; realpath(".", __stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(realpath_heap_before_end); ATF_TC_BODY(realpath_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX + 1); const size_t __len = PATH_MAX + 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); realpath(".", __stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(realpath_heap_end); ATF_TC_BODY(realpath_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX); const size_t __len = PATH_MAX; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); realpath(".", __stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(realpath_heap_after_end); ATF_TC_BODY(realpath_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (PATH_MAX - 1); const size_t __len = PATH_MAX - 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); realpath(".", __stack.__buf); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, arc4random_buf_before_end); ATF_TP_ADD_TC(tp, arc4random_buf_end); ATF_TP_ADD_TC(tp, arc4random_buf_heap_before_end); ATF_TP_ADD_TC(tp, arc4random_buf_heap_end); ATF_TP_ADD_TC(tp, arc4random_buf_heap_after_end); ATF_TP_ADD_TC(tp, realpath_before_end); ATF_TP_ADD_TC(tp, realpath_end); ATF_TP_ADD_TC(tp, realpath_heap_before_end); ATF_TP_ADD_TC(tp, realpath_heap_end); ATF_TP_ADD_TC(tp, realpath_heap_after_end); return (atf_no_error()); } diff --git a/lib/libc/tests/secure/fortify_string_test.c b/lib/libc/tests/secure/fortify_string_test.c index 5651d3107e91..0ba1cf0160b4 100644 --- a/lib/libc/tests/secure/fortify_string_test.c +++ b/lib/libc/tests/secure/fortify_string_test.c @@ -1,1894 +1,1895 @@ /* @generated by `generate-fortify-tests.lua "string"` */ #define _FORTIFY_SOURCE 2 #define TMPFILE_SIZE (1024 * 32) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include static FILE * __unused new_fp(size_t __len) { static char fpbuf[LINE_MAX]; FILE *fp; ATF_REQUIRE(__len <= sizeof(fpbuf)); memset(fpbuf, 'A', sizeof(fpbuf) - 1); fpbuf[sizeof(fpbuf) - 1] = '\0'; fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); ATF_REQUIRE(fp != NULL); return (fp); } /* * Create a new symlink to use for readlink(2) style tests, we'll just use a * random target name to have something interesting to look at. */ static const char * __unused new_symlink(size_t __len) { static const char linkname[] = "link"; char target[MAXNAMLEN]; int error; ATF_REQUIRE(__len <= sizeof(target)); arc4random_buf(target, sizeof(target)); error = unlink(linkname); ATF_REQUIRE(error == 0 || errno == ENOENT); error = symlink(target, linkname); ATF_REQUIRE(error == 0); return (linkname); } /* * Constructs a tmpfile that we can use for testing read(2) and friends. */ static int __unused new_tmpfile(void) { char buf[1024]; ssize_t rv; size_t written; int fd; fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); ATF_REQUIRE(fd >= 0); written = 0; while (written < TMPFILE_SIZE) { rv = write(fd, buf, sizeof(buf)); ATF_REQUIRE(rv > 0); written += rv; } ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); return (fd); } static void disable_coredumps(void) { struct rlimit rl = { 0 }; if (setrlimit(RLIMIT_CORE, &rl) == -1) _exit(EX_OSERR); } /* * Replaces stdin with a file that we can actually read from, for tests where * we want a FILE * or fd that we can get data from. */ static void __unused replace_stdin(void) { int fd; fd = new_tmpfile(); (void)dup2(fd, STDIN_FILENO); if (fd != STDIN_FILENO) close(fd); } ATF_TC_WITHOUT_HEAD(memcpy_before_end); ATF_TC_BODY(memcpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len + 10]; memcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memcpy_end); ATF_TC_BODY(memcpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len + 10]; memcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memcpy_heap_before_end); ATF_TC_BODY(memcpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len + 10]; __stack.__buf = malloc(__bufsz); memcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memcpy_heap_end); ATF_TC_BODY(memcpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len + 10]; __stack.__buf = malloc(__bufsz); memcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memcpy_heap_after_end); ATF_TC_BODY(memcpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len + 10]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memcpy(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(mempcpy_before_end); ATF_TC_BODY(mempcpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len + 10]; mempcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(mempcpy_end); ATF_TC_BODY(mempcpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len + 10]; mempcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(mempcpy_heap_before_end); ATF_TC_BODY(mempcpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len + 10]; __stack.__buf = malloc(__bufsz); mempcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(mempcpy_heap_end); ATF_TC_BODY(mempcpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len + 10]; __stack.__buf = malloc(__bufsz); mempcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(mempcpy_heap_after_end); ATF_TC_BODY(mempcpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len + 10]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); mempcpy(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(memmove_before_end); ATF_TC_BODY(memmove_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len + 10]; memmove(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memmove_end); ATF_TC_BODY(memmove_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len + 10]; memmove(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memmove_heap_before_end); ATF_TC_BODY(memmove_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len + 10]; __stack.__buf = malloc(__bufsz); memmove(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memmove_heap_end); ATF_TC_BODY(memmove_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len + 10]; __stack.__buf = malloc(__bufsz); memmove(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memmove_heap_after_end); ATF_TC_BODY(memmove_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len + 10]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memmove(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(memset_before_end); ATF_TC_BODY(memset_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; memset(__stack.__buf, 0, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memset_end); ATF_TC_BODY(memset_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; memset(__stack.__buf, 0, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memset_heap_before_end); ATF_TC_BODY(memset_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memset_heap_end); ATF_TC_BODY(memset_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(memset_heap_after_end); ATF_TC_BODY(memset_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(stpcpy_before_end); ATF_TC_BODY(stpcpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; stpcpy(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(stpcpy_end); ATF_TC_BODY(stpcpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; stpcpy(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(stpcpy_heap_before_end); ATF_TC_BODY(stpcpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; stpcpy(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(stpcpy_heap_end); ATF_TC_BODY(stpcpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; stpcpy(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(stpcpy_heap_after_end); ATF_TC_BODY(stpcpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; stpcpy(__stack.__buf, src); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(stpncpy_before_end); ATF_TC_BODY(stpncpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; stpncpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(stpncpy_end); ATF_TC_BODY(stpncpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; stpncpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(stpncpy_heap_before_end); ATF_TC_BODY(stpncpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; stpncpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(stpncpy_heap_end); ATF_TC_BODY(stpncpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; stpncpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(stpncpy_heap_after_end); ATF_TC_BODY(stpncpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; stpncpy(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(strcat_before_end); ATF_TC_BODY(strcat_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strcat(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(strcat_end); ATF_TC_BODY(strcat_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strcat(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(strcat_heap_before_end); ATF_TC_BODY(strcat_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strcat(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(strcat_heap_end); ATF_TC_BODY(strcat_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strcat(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(strcat_heap_after_end); ATF_TC_BODY(strcat_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strcat(__stack.__buf, src); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(strlcat_before_end); ATF_TC_BODY(strlcat_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strlcat(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strlcat_end); ATF_TC_BODY(strlcat_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strlcat(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strlcat_heap_before_end); ATF_TC_BODY(strlcat_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strlcat(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strlcat_heap_end); ATF_TC_BODY(strlcat_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strlcat(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strlcat_heap_after_end); ATF_TC_BODY(strlcat_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strlcat(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(strncat_before_end); ATF_TC_BODY(strncat_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strncat(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strncat_end); ATF_TC_BODY(strncat_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strncat(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strncat_heap_before_end); ATF_TC_BODY(strncat_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strncat(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strncat_heap_end); ATF_TC_BODY(strncat_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strncat(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strncat_heap_after_end); ATF_TC_BODY(strncat_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strncat(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(strcpy_before_end); ATF_TC_BODY(strcpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strcpy(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(strcpy_end); ATF_TC_BODY(strcpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strcpy(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(strcpy_heap_before_end); ATF_TC_BODY(strcpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strcpy(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(strcpy_heap_end); ATF_TC_BODY(strcpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strcpy(__stack.__buf, src); #undef BUF } ATF_TC_WITHOUT_HEAD(strcpy_heap_after_end); ATF_TC_BODY(strcpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strcpy(__stack.__buf, src); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(strlcpy_before_end); ATF_TC_BODY(strlcpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strlcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strlcpy_end); ATF_TC_BODY(strlcpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strlcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strlcpy_heap_before_end); ATF_TC_BODY(strlcpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strlcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strlcpy_heap_end); ATF_TC_BODY(strlcpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strlcpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strlcpy_heap_after_end); ATF_TC_BODY(strlcpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strlcpy(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(strncpy_before_end); ATF_TC_BODY(strncpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strncpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strncpy_end); ATF_TC_BODY(strncpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strncpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strncpy_heap_before_end); ATF_TC_BODY(strncpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strncpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strncpy_heap_end); ATF_TC_BODY(strncpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len]; __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strncpy(__stack.__buf, src, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(strncpy_heap_after_end); ATF_TC_BODY(strncpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; strncpy(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, memcpy_before_end); ATF_TP_ADD_TC(tp, memcpy_end); ATF_TP_ADD_TC(tp, memcpy_heap_before_end); ATF_TP_ADD_TC(tp, memcpy_heap_end); ATF_TP_ADD_TC(tp, memcpy_heap_after_end); ATF_TP_ADD_TC(tp, mempcpy_before_end); ATF_TP_ADD_TC(tp, mempcpy_end); ATF_TP_ADD_TC(tp, mempcpy_heap_before_end); ATF_TP_ADD_TC(tp, mempcpy_heap_end); ATF_TP_ADD_TC(tp, mempcpy_heap_after_end); ATF_TP_ADD_TC(tp, memmove_before_end); ATF_TP_ADD_TC(tp, memmove_end); ATF_TP_ADD_TC(tp, memmove_heap_before_end); ATF_TP_ADD_TC(tp, memmove_heap_end); ATF_TP_ADD_TC(tp, memmove_heap_after_end); ATF_TP_ADD_TC(tp, memset_before_end); ATF_TP_ADD_TC(tp, memset_end); ATF_TP_ADD_TC(tp, memset_heap_before_end); ATF_TP_ADD_TC(tp, memset_heap_end); ATF_TP_ADD_TC(tp, memset_heap_after_end); ATF_TP_ADD_TC(tp, stpcpy_before_end); ATF_TP_ADD_TC(tp, stpcpy_end); ATF_TP_ADD_TC(tp, stpcpy_heap_before_end); ATF_TP_ADD_TC(tp, stpcpy_heap_end); ATF_TP_ADD_TC(tp, stpcpy_heap_after_end); ATF_TP_ADD_TC(tp, stpncpy_before_end); ATF_TP_ADD_TC(tp, stpncpy_end); ATF_TP_ADD_TC(tp, stpncpy_heap_before_end); ATF_TP_ADD_TC(tp, stpncpy_heap_end); ATF_TP_ADD_TC(tp, stpncpy_heap_after_end); ATF_TP_ADD_TC(tp, strcat_before_end); ATF_TP_ADD_TC(tp, strcat_end); ATF_TP_ADD_TC(tp, strcat_heap_before_end); ATF_TP_ADD_TC(tp, strcat_heap_end); ATF_TP_ADD_TC(tp, strcat_heap_after_end); ATF_TP_ADD_TC(tp, strlcat_before_end); ATF_TP_ADD_TC(tp, strlcat_end); ATF_TP_ADD_TC(tp, strlcat_heap_before_end); ATF_TP_ADD_TC(tp, strlcat_heap_end); ATF_TP_ADD_TC(tp, strlcat_heap_after_end); ATF_TP_ADD_TC(tp, strncat_before_end); ATF_TP_ADD_TC(tp, strncat_end); ATF_TP_ADD_TC(tp, strncat_heap_before_end); ATF_TP_ADD_TC(tp, strncat_heap_end); ATF_TP_ADD_TC(tp, strncat_heap_after_end); ATF_TP_ADD_TC(tp, strcpy_before_end); ATF_TP_ADD_TC(tp, strcpy_end); ATF_TP_ADD_TC(tp, strcpy_heap_before_end); ATF_TP_ADD_TC(tp, strcpy_heap_end); ATF_TP_ADD_TC(tp, strcpy_heap_after_end); ATF_TP_ADD_TC(tp, strlcpy_before_end); ATF_TP_ADD_TC(tp, strlcpy_end); ATF_TP_ADD_TC(tp, strlcpy_heap_before_end); ATF_TP_ADD_TC(tp, strlcpy_heap_end); ATF_TP_ADD_TC(tp, strlcpy_heap_after_end); ATF_TP_ADD_TC(tp, strncpy_before_end); ATF_TP_ADD_TC(tp, strncpy_end); ATF_TP_ADD_TC(tp, strncpy_heap_before_end); ATF_TP_ADD_TC(tp, strncpy_heap_end); ATF_TP_ADD_TC(tp, strncpy_heap_after_end); return (atf_no_error()); } diff --git a/lib/libc/tests/secure/fortify_strings_test.c b/lib/libc/tests/secure/fortify_strings_test.c index 28f5e9ec4940..a476564f1596 100644 --- a/lib/libc/tests/secure/fortify_strings_test.c +++ b/lib/libc/tests/secure/fortify_strings_test.c @@ -1,520 +1,521 @@ /* @generated by `generate-fortify-tests.lua "strings"` */ #define _FORTIFY_SOURCE 2 #define TMPFILE_SIZE (1024 * 32) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include static FILE * __unused new_fp(size_t __len) { static char fpbuf[LINE_MAX]; FILE *fp; ATF_REQUIRE(__len <= sizeof(fpbuf)); memset(fpbuf, 'A', sizeof(fpbuf) - 1); fpbuf[sizeof(fpbuf) - 1] = '\0'; fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); ATF_REQUIRE(fp != NULL); return (fp); } /* * Create a new symlink to use for readlink(2) style tests, we'll just use a * random target name to have something interesting to look at. */ static const char * __unused new_symlink(size_t __len) { static const char linkname[] = "link"; char target[MAXNAMLEN]; int error; ATF_REQUIRE(__len <= sizeof(target)); arc4random_buf(target, sizeof(target)); error = unlink(linkname); ATF_REQUIRE(error == 0 || errno == ENOENT); error = symlink(target, linkname); ATF_REQUIRE(error == 0); return (linkname); } /* * Constructs a tmpfile that we can use for testing read(2) and friends. */ static int __unused new_tmpfile(void) { char buf[1024]; ssize_t rv; size_t written; int fd; fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); ATF_REQUIRE(fd >= 0); written = 0; while (written < TMPFILE_SIZE) { rv = write(fd, buf, sizeof(buf)); ATF_REQUIRE(rv > 0); written += rv; } ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); return (fd); } static void disable_coredumps(void) { struct rlimit rl = { 0 }; if (setrlimit(RLIMIT_CORE, &rl) == -1) _exit(EX_OSERR); } /* * Replaces stdin with a file that we can actually read from, for tests where * we want a FILE * or fd that we can get data from. */ static void __unused replace_stdin(void) { int fd; fd = new_tmpfile(); (void)dup2(fd, STDIN_FILENO); if (fd != STDIN_FILENO) close(fd); } ATF_TC_WITHOUT_HEAD(bcopy_before_end); ATF_TC_BODY(bcopy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len + 10]; bcopy(src, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(bcopy_end); ATF_TC_BODY(bcopy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len + 10]; bcopy(src, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(bcopy_heap_before_end); ATF_TC_BODY(bcopy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; char src[__len + 10]; __stack.__buf = malloc(__bufsz); bcopy(src, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(bcopy_heap_end); ATF_TC_BODY(bcopy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; char src[__len + 10]; __stack.__buf = malloc(__bufsz); bcopy(src, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(bcopy_heap_after_end); ATF_TC_BODY(bcopy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char src[__len + 10]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); bcopy(src, __stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(bzero_before_end); ATF_TC_BODY(bzero_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; bzero(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(bzero_end); ATF_TC_BODY(bzero_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; bzero(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(bzero_heap_before_end); ATF_TC_BODY(bzero_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); bzero(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(bzero_heap_end); ATF_TC_BODY(bzero_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); bzero(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(bzero_heap_after_end); ATF_TC_BODY(bzero_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); bzero(__stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(explicit_bzero_before_end); ATF_TC_BODY(explicit_bzero_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; explicit_bzero(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(explicit_bzero_end); ATF_TC_BODY(explicit_bzero_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; explicit_bzero(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_before_end); ATF_TC_BODY(explicit_bzero_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); explicit_bzero(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_end); ATF_TC_BODY(explicit_bzero_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); explicit_bzero(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_after_end); ATF_TC_BODY(explicit_bzero_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); explicit_bzero(__stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, bcopy_before_end); ATF_TP_ADD_TC(tp, bcopy_end); ATF_TP_ADD_TC(tp, bcopy_heap_before_end); ATF_TP_ADD_TC(tp, bcopy_heap_end); ATF_TP_ADD_TC(tp, bcopy_heap_after_end); ATF_TP_ADD_TC(tp, bzero_before_end); ATF_TP_ADD_TC(tp, bzero_end); ATF_TP_ADD_TC(tp, bzero_heap_before_end); ATF_TP_ADD_TC(tp, bzero_heap_end); ATF_TP_ADD_TC(tp, bzero_heap_after_end); ATF_TP_ADD_TC(tp, explicit_bzero_before_end); ATF_TP_ADD_TC(tp, explicit_bzero_end); ATF_TP_ADD_TC(tp, explicit_bzero_heap_before_end); ATF_TP_ADD_TC(tp, explicit_bzero_heap_end); ATF_TP_ADD_TC(tp, explicit_bzero_heap_after_end); return (atf_no_error()); } diff --git a/lib/libc/tests/secure/fortify_unistd_test.c b/lib/libc/tests/secure/fortify_unistd_test.c index dddc23596368..cfd9267d0d79 100644 --- a/lib/libc/tests/secure/fortify_unistd_test.c +++ b/lib/libc/tests/secure/fortify_unistd_test.c @@ -1,1968 +1,1969 @@ /* @generated by `generate-fortify-tests.lua "unistd"` */ #define _FORTIFY_SOURCE 2 #define TMPFILE_SIZE (1024 * 32) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include static FILE * __unused new_fp(size_t __len) { static char fpbuf[LINE_MAX]; FILE *fp; ATF_REQUIRE(__len <= sizeof(fpbuf)); memset(fpbuf, 'A', sizeof(fpbuf) - 1); fpbuf[sizeof(fpbuf) - 1] = '\0'; fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); ATF_REQUIRE(fp != NULL); return (fp); } /* * Create a new symlink to use for readlink(2) style tests, we'll just use a * random target name to have something interesting to look at. */ static const char * __unused new_symlink(size_t __len) { static const char linkname[] = "link"; char target[MAXNAMLEN]; int error; ATF_REQUIRE(__len <= sizeof(target)); arc4random_buf(target, sizeof(target)); error = unlink(linkname); ATF_REQUIRE(error == 0 || errno == ENOENT); error = symlink(target, linkname); ATF_REQUIRE(error == 0); return (linkname); } /* * Constructs a tmpfile that we can use for testing read(2) and friends. */ static int __unused new_tmpfile(void) { char buf[1024]; ssize_t rv; size_t written; int fd; fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); ATF_REQUIRE(fd >= 0); written = 0; while (written < TMPFILE_SIZE) { rv = write(fd, buf, sizeof(buf)); ATF_REQUIRE(rv > 0); written += rv; } ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); return (fd); } static void disable_coredumps(void) { struct rlimit rl = { 0 }; if (setrlimit(RLIMIT_CORE, &rl) == -1) _exit(EX_OSERR); } /* * Replaces stdin with a file that we can actually read from, for tests where * we want a FILE * or fd that we can get data from. */ static void __unused replace_stdin(void) { int fd; fd = new_tmpfile(); (void)dup2(fd, STDIN_FILENO); if (fd != STDIN_FILENO) close(fd); } ATF_TC_WITHOUT_HEAD(getcwd_before_end); ATF_TC_BODY(getcwd_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[8]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 8 - 1; const size_t __idx __unused = __len - 1; getcwd(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getcwd_end); ATF_TC_BODY(getcwd_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[8]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 8; const size_t __idx __unused = __len - 1; getcwd(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getcwd_heap_before_end); ATF_TC_BODY(getcwd_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (8); const size_t __len = 8 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); getcwd(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getcwd_heap_end); ATF_TC_BODY(getcwd_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (8); const size_t __len = 8; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); getcwd(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getcwd_heap_after_end); ATF_TC_BODY(getcwd_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (8); const size_t __len = 8 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); getcwd(__stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(getgrouplist_before_end); ATF_TC_BODY(getgrouplist_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; gid_t __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; int intlen = (int)__len; getgrouplist("root", 0, __stack.__buf, &intlen); #undef BUF } ATF_TC_WITHOUT_HEAD(getgrouplist_end); ATF_TC_BODY(getgrouplist_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; gid_t __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4; const size_t __idx __unused = __len - 1; int intlen = (int)__len; getgrouplist("root", 0, __stack.__buf, &intlen); #undef BUF } ATF_TC_WITHOUT_HEAD(getgrouplist_heap_before_end); ATF_TC_BODY(getgrouplist_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; gid_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; int intlen = (int)__len; __stack.__buf = malloc(__bufsz); getgrouplist("root", 0, __stack.__buf, &intlen); #undef BUF } ATF_TC_WITHOUT_HEAD(getgrouplist_heap_end); ATF_TC_BODY(getgrouplist_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; gid_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4; const size_t __idx __unused = __len - 1; int intlen = (int)__len; __stack.__buf = malloc(__bufsz); getgrouplist("root", 0, __stack.__buf, &intlen); #undef BUF } ATF_TC_WITHOUT_HEAD(getgrouplist_heap_after_end); ATF_TC_BODY(getgrouplist_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; gid_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; int intlen = (int)__len; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); getgrouplist("root", 0, __stack.__buf, &intlen); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(getgroups_before_end); ATF_TC_BODY(getgroups_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; gid_t __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; getgroups(__len, __stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(getgroups_end); ATF_TC_BODY(getgroups_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; gid_t __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4; const size_t __idx __unused = __len - 1; getgroups(__len, __stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(getgroups_heap_before_end); ATF_TC_BODY(getgroups_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; gid_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); getgroups(__len, __stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(getgroups_heap_end); ATF_TC_BODY(getgroups_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; gid_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); getgroups(__len, __stack.__buf); #undef BUF } ATF_TC_WITHOUT_HEAD(getgroups_heap_after_end); ATF_TC_BODY(getgroups_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; gid_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); getgroups(__len, __stack.__buf); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(getloginclass_before_end); ATF_TC_BODY(getloginclass_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; getloginclass(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getloginclass_end); ATF_TC_BODY(getloginclass_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; getloginclass(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getloginclass_heap_before_end); ATF_TC_BODY(getloginclass_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); getloginclass(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getloginclass_heap_end); ATF_TC_BODY(getloginclass_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); getloginclass(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getloginclass_heap_after_end); ATF_TC_BODY(getloginclass_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); getloginclass(__stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(pread_before_end); ATF_TC_BODY(pread_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[41]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 41 - 1; const size_t __idx __unused = __len - 1; int fd; fd = new_tmpfile(); /* Cannot fail */ pread(fd, __stack.__buf, __len, 0); #undef BUF } ATF_TC_WITHOUT_HEAD(pread_end); ATF_TC_BODY(pread_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[41]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 41; const size_t __idx __unused = __len - 1; int fd; fd = new_tmpfile(); /* Cannot fail */ pread(fd, __stack.__buf, __len, 0); #undef BUF } ATF_TC_WITHOUT_HEAD(pread_heap_before_end); ATF_TC_BODY(pread_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (41); const size_t __len = 41 - 1; const size_t __idx __unused = __len - 1; int fd; __stack.__buf = malloc(__bufsz); fd = new_tmpfile(); /* Cannot fail */ pread(fd, __stack.__buf, __len, 0); #undef BUF } ATF_TC_WITHOUT_HEAD(pread_heap_end); ATF_TC_BODY(pread_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (41); const size_t __len = 41; const size_t __idx __unused = __len - 1; int fd; __stack.__buf = malloc(__bufsz); fd = new_tmpfile(); /* Cannot fail */ pread(fd, __stack.__buf, __len, 0); #undef BUF } ATF_TC_WITHOUT_HEAD(pread_heap_after_end); ATF_TC_BODY(pread_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (41); const size_t __len = 41 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; int fd; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); fd = new_tmpfile(); /* Cannot fail */ pread(fd, __stack.__buf, __len, 0); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(read_before_end); ATF_TC_BODY(read_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[41]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 41 - 1; const size_t __idx __unused = __len - 1; int fd; fd = new_tmpfile(); /* Cannot fail */ read(fd, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(read_end); ATF_TC_BODY(read_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[41]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 41; const size_t __idx __unused = __len - 1; int fd; fd = new_tmpfile(); /* Cannot fail */ read(fd, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(read_heap_before_end); ATF_TC_BODY(read_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (41); const size_t __len = 41 - 1; const size_t __idx __unused = __len - 1; int fd; __stack.__buf = malloc(__bufsz); fd = new_tmpfile(); /* Cannot fail */ read(fd, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(read_heap_end); ATF_TC_BODY(read_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (41); const size_t __len = 41; const size_t __idx __unused = __len - 1; int fd; __stack.__buf = malloc(__bufsz); fd = new_tmpfile(); /* Cannot fail */ read(fd, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(read_heap_after_end); ATF_TC_BODY(read_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (41); const size_t __len = 41 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; int fd; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); fd = new_tmpfile(); /* Cannot fail */ read(fd, __stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(readlink_before_end); ATF_TC_BODY(readlink_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; const char *path; path = new_symlink(__len); /* Cannot fail */ readlink(path, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(readlink_end); ATF_TC_BODY(readlink_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; const char *path; path = new_symlink(__len); /* Cannot fail */ readlink(path, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(readlink_heap_before_end); ATF_TC_BODY(readlink_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; const char *path; __stack.__buf = malloc(__bufsz); path = new_symlink(__len); /* Cannot fail */ readlink(path, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(readlink_heap_end); ATF_TC_BODY(readlink_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; const char *path; __stack.__buf = malloc(__bufsz); path = new_symlink(__len); /* Cannot fail */ readlink(path, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(readlink_heap_after_end); ATF_TC_BODY(readlink_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; const char *path; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); path = new_symlink(__len); /* Cannot fail */ readlink(path, __stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(readlinkat_before_end); ATF_TC_BODY(readlinkat_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; const char *path; path = new_symlink(__len); /* Cannot fail */ readlinkat(AT_FDCWD, path, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(readlinkat_end); ATF_TC_BODY(readlinkat_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; const char *path; path = new_symlink(__len); /* Cannot fail */ readlinkat(AT_FDCWD, path, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(readlinkat_heap_before_end); ATF_TC_BODY(readlinkat_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; const char *path; __stack.__buf = malloc(__bufsz); path = new_symlink(__len); /* Cannot fail */ readlinkat(AT_FDCWD, path, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(readlinkat_heap_end); ATF_TC_BODY(readlinkat_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; const char *path; __stack.__buf = malloc(__bufsz); path = new_symlink(__len); /* Cannot fail */ readlinkat(AT_FDCWD, path, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(readlinkat_heap_after_end); ATF_TC_BODY(readlinkat_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; const char *path; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); path = new_symlink(__len); /* Cannot fail */ readlinkat(AT_FDCWD, path, __stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(getdomainname_before_end); ATF_TC_BODY(getdomainname_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; char sysdomain[256]; (void)getdomainname(sysdomain, __len); if (strlen(sysdomain) <= __len) atf_tc_skip("domain name too short for testing"); getdomainname(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getdomainname_end); ATF_TC_BODY(getdomainname_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4; const size_t __idx __unused = __len - 1; char sysdomain[256]; (void)getdomainname(sysdomain, __len); if (strlen(sysdomain) <= __len) atf_tc_skip("domain name too short for testing"); getdomainname(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getdomainname_heap_before_end); ATF_TC_BODY(getdomainname_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; char sysdomain[256]; (void)getdomainname(sysdomain, __len); if (strlen(sysdomain) <= __len) atf_tc_skip("domain name too short for testing"); __stack.__buf = malloc(__bufsz); getdomainname(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getdomainname_heap_end); ATF_TC_BODY(getdomainname_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4; const size_t __idx __unused = __len - 1; char sysdomain[256]; (void)getdomainname(sysdomain, __len); if (strlen(sysdomain) <= __len) atf_tc_skip("domain name too short for testing"); __stack.__buf = malloc(__bufsz); getdomainname(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getdomainname_heap_after_end); ATF_TC_BODY(getdomainname_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char sysdomain[256]; (void)getdomainname(sysdomain, __len); if (strlen(sysdomain) <= __len) atf_tc_skip("domain name too short for testing"); __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); getdomainname(__stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(getentropy_before_end); ATF_TC_BODY(getentropy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; getentropy(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getentropy_end); ATF_TC_BODY(getentropy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; getentropy(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getentropy_heap_before_end); ATF_TC_BODY(getentropy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); getentropy(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getentropy_heap_end); ATF_TC_BODY(getentropy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); getentropy(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getentropy_heap_after_end); ATF_TC_BODY(getentropy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); getentropy(__stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(gethostname_before_end); ATF_TC_BODY(gethostname_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; char syshost[256]; int error; error = gethostname(syshost, __len); if (error != 0 || strlen(syshost) <= __len) atf_tc_skip("hostname too short for testing"); gethostname(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(gethostname_end); ATF_TC_BODY(gethostname_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[4]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 4; const size_t __idx __unused = __len - 1; char syshost[256]; int error; error = gethostname(syshost, __len); if (error != 0 || strlen(syshost) <= __len) atf_tc_skip("hostname too short for testing"); gethostname(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(gethostname_heap_before_end); ATF_TC_BODY(gethostname_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 - 1; const size_t __idx __unused = __len - 1; char syshost[256]; int error; error = gethostname(syshost, __len); if (error != 0 || strlen(syshost) <= __len) atf_tc_skip("hostname too short for testing"); __stack.__buf = malloc(__bufsz); gethostname(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(gethostname_heap_end); ATF_TC_BODY(gethostname_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4; const size_t __idx __unused = __len - 1; char syshost[256]; int error; error = gethostname(syshost, __len); if (error != 0 || strlen(syshost) <= __len) atf_tc_skip("hostname too short for testing"); __stack.__buf = malloc(__bufsz); gethostname(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(gethostname_heap_after_end); ATF_TC_BODY(gethostname_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4); const size_t __len = 4 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; char syshost[256]; int error; error = gethostname(syshost, __len); if (error != 0 || strlen(syshost) <= __len) atf_tc_skip("hostname too short for testing"); __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); gethostname(__stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(getlogin_r_before_end); ATF_TC_BODY(getlogin_r_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[MAXLOGNAME + 1]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = MAXLOGNAME + 1 - 1; const size_t __idx __unused = __len - 1; getlogin_r(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getlogin_r_end); ATF_TC_BODY(getlogin_r_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[MAXLOGNAME + 1]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = MAXLOGNAME + 1; const size_t __idx __unused = __len - 1; getlogin_r(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getlogin_r_heap_before_end); ATF_TC_BODY(getlogin_r_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (MAXLOGNAME + 1); const size_t __len = MAXLOGNAME + 1 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); getlogin_r(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getlogin_r_heap_end); ATF_TC_BODY(getlogin_r_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (MAXLOGNAME + 1); const size_t __len = MAXLOGNAME + 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); getlogin_r(__stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(getlogin_r_heap_after_end); ATF_TC_BODY(getlogin_r_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (MAXLOGNAME + 1); const size_t __len = MAXLOGNAME + 1 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); getlogin_r(__stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TC_WITHOUT_HEAD(ttyname_r_before_end); ATF_TC_BODY(ttyname_r_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; int fd; fd = STDIN_FILENO; if (!isatty(fd)) atf_tc_skip("stdin is not an fd"); ttyname_r(fd, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(ttyname_r_end); ATF_TC_BODY(ttyname_r_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; unsigned char __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; int fd; fd = STDIN_FILENO; if (!isatty(fd)) atf_tc_skip("stdin is not an fd"); ttyname_r(fd, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(ttyname_r_heap_before_end); ATF_TC_BODY(ttyname_r_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; int fd; fd = STDIN_FILENO; if (!isatty(fd)) atf_tc_skip("stdin is not an fd"); __stack.__buf = malloc(__bufsz); ttyname_r(fd, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(ttyname_r_heap_end); ATF_TC_BODY(ttyname_r_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; int fd; fd = STDIN_FILENO; if (!isatty(fd)) atf_tc_skip("stdin is not an fd"); __stack.__buf = malloc(__bufsz); ttyname_r(fd, __stack.__buf, __len); #undef BUF } ATF_TC_WITHOUT_HEAD(ttyname_r_heap_after_end); ATF_TC_BODY(ttyname_r_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; unsigned char * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; int fd; fd = STDIN_FILENO; if (!isatty(fd)) atf_tc_skip("stdin is not an fd"); __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); ttyname_r(fd, __stack.__buf, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, getcwd_before_end); ATF_TP_ADD_TC(tp, getcwd_end); ATF_TP_ADD_TC(tp, getcwd_heap_before_end); ATF_TP_ADD_TC(tp, getcwd_heap_end); ATF_TP_ADD_TC(tp, getcwd_heap_after_end); ATF_TP_ADD_TC(tp, getgrouplist_before_end); ATF_TP_ADD_TC(tp, getgrouplist_end); ATF_TP_ADD_TC(tp, getgrouplist_heap_before_end); ATF_TP_ADD_TC(tp, getgrouplist_heap_end); ATF_TP_ADD_TC(tp, getgrouplist_heap_after_end); ATF_TP_ADD_TC(tp, getgroups_before_end); ATF_TP_ADD_TC(tp, getgroups_end); ATF_TP_ADD_TC(tp, getgroups_heap_before_end); ATF_TP_ADD_TC(tp, getgroups_heap_end); ATF_TP_ADD_TC(tp, getgroups_heap_after_end); ATF_TP_ADD_TC(tp, getloginclass_before_end); ATF_TP_ADD_TC(tp, getloginclass_end); ATF_TP_ADD_TC(tp, getloginclass_heap_before_end); ATF_TP_ADD_TC(tp, getloginclass_heap_end); ATF_TP_ADD_TC(tp, getloginclass_heap_after_end); ATF_TP_ADD_TC(tp, pread_before_end); ATF_TP_ADD_TC(tp, pread_end); ATF_TP_ADD_TC(tp, pread_heap_before_end); ATF_TP_ADD_TC(tp, pread_heap_end); ATF_TP_ADD_TC(tp, pread_heap_after_end); ATF_TP_ADD_TC(tp, read_before_end); ATF_TP_ADD_TC(tp, read_end); ATF_TP_ADD_TC(tp, read_heap_before_end); ATF_TP_ADD_TC(tp, read_heap_end); ATF_TP_ADD_TC(tp, read_heap_after_end); ATF_TP_ADD_TC(tp, readlink_before_end); ATF_TP_ADD_TC(tp, readlink_end); ATF_TP_ADD_TC(tp, readlink_heap_before_end); ATF_TP_ADD_TC(tp, readlink_heap_end); ATF_TP_ADD_TC(tp, readlink_heap_after_end); ATF_TP_ADD_TC(tp, readlinkat_before_end); ATF_TP_ADD_TC(tp, readlinkat_end); ATF_TP_ADD_TC(tp, readlinkat_heap_before_end); ATF_TP_ADD_TC(tp, readlinkat_heap_end); ATF_TP_ADD_TC(tp, readlinkat_heap_after_end); ATF_TP_ADD_TC(tp, getdomainname_before_end); ATF_TP_ADD_TC(tp, getdomainname_end); ATF_TP_ADD_TC(tp, getdomainname_heap_before_end); ATF_TP_ADD_TC(tp, getdomainname_heap_end); ATF_TP_ADD_TC(tp, getdomainname_heap_after_end); ATF_TP_ADD_TC(tp, getentropy_before_end); ATF_TP_ADD_TC(tp, getentropy_end); ATF_TP_ADD_TC(tp, getentropy_heap_before_end); ATF_TP_ADD_TC(tp, getentropy_heap_end); ATF_TP_ADD_TC(tp, getentropy_heap_after_end); ATF_TP_ADD_TC(tp, gethostname_before_end); ATF_TP_ADD_TC(tp, gethostname_end); ATF_TP_ADD_TC(tp, gethostname_heap_before_end); ATF_TP_ADD_TC(tp, gethostname_heap_end); ATF_TP_ADD_TC(tp, gethostname_heap_after_end); ATF_TP_ADD_TC(tp, getlogin_r_before_end); ATF_TP_ADD_TC(tp, getlogin_r_end); ATF_TP_ADD_TC(tp, getlogin_r_heap_before_end); ATF_TP_ADD_TC(tp, getlogin_r_heap_end); ATF_TP_ADD_TC(tp, getlogin_r_heap_after_end); ATF_TP_ADD_TC(tp, ttyname_r_before_end); ATF_TP_ADD_TC(tp, ttyname_r_end); ATF_TP_ADD_TC(tp, ttyname_r_heap_before_end); ATF_TP_ADD_TC(tp, ttyname_r_heap_end); ATF_TP_ADD_TC(tp, ttyname_r_heap_after_end); return (atf_no_error()); } diff --git a/lib/libc/tests/secure/fortify_string_test.c b/lib/libc/tests/secure/fortify_wchar_test.c similarity index 65% copy from lib/libc/tests/secure/fortify_string_test.c copy to lib/libc/tests/secure/fortify_wchar_test.c index 5651d3107e91..f02e4045c8f2 100644 --- a/lib/libc/tests/secure/fortify_string_test.c +++ b/lib/libc/tests/secure/fortify_wchar_test.c @@ -1,1894 +1,1895 @@ -/* @generated by `generate-fortify-tests.lua "string"` */ +/* @generated by `generate-fortify-tests.lua "wchar"` */ #define _FORTIFY_SOURCE 2 #define TMPFILE_SIZE (1024 * 32) #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include static FILE * __unused new_fp(size_t __len) { static char fpbuf[LINE_MAX]; FILE *fp; ATF_REQUIRE(__len <= sizeof(fpbuf)); memset(fpbuf, 'A', sizeof(fpbuf) - 1); fpbuf[sizeof(fpbuf) - 1] = '\0'; fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); ATF_REQUIRE(fp != NULL); return (fp); } /* * Create a new symlink to use for readlink(2) style tests, we'll just use a * random target name to have something interesting to look at. */ static const char * __unused new_symlink(size_t __len) { static const char linkname[] = "link"; char target[MAXNAMLEN]; int error; ATF_REQUIRE(__len <= sizeof(target)); arc4random_buf(target, sizeof(target)); error = unlink(linkname); ATF_REQUIRE(error == 0 || errno == ENOENT); error = symlink(target, linkname); ATF_REQUIRE(error == 0); return (linkname); } /* * Constructs a tmpfile that we can use for testing read(2) and friends. */ static int __unused new_tmpfile(void) { char buf[1024]; ssize_t rv; size_t written; int fd; fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); ATF_REQUIRE(fd >= 0); written = 0; while (written < TMPFILE_SIZE) { rv = write(fd, buf, sizeof(buf)); ATF_REQUIRE(rv > 0); written += rv; } ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); return (fd); } static void disable_coredumps(void) { struct rlimit rl = { 0 }; if (setrlimit(RLIMIT_CORE, &rl) == -1) _exit(EX_OSERR); } /* * Replaces stdin with a file that we can actually read from, for tests where * we want a FILE * or fd that we can get data from. */ static void __unused replace_stdin(void) { int fd; fd = new_tmpfile(); (void)dup2(fd, STDIN_FILENO); if (fd != STDIN_FILENO) close(fd); } -ATF_TC_WITHOUT_HEAD(memcpy_before_end); -ATF_TC_BODY(memcpy_before_end, tc) +ATF_TC_WITHOUT_HEAD(wmemcpy_before_end); +ATF_TC_BODY(wmemcpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; - memcpy(__stack.__buf, src, __len); + wmemcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memcpy_end); -ATF_TC_BODY(memcpy_end, tc) +ATF_TC_WITHOUT_HEAD(wmemcpy_end); +ATF_TC_BODY(wmemcpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; - memcpy(__stack.__buf, src, __len); + wmemcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memcpy_heap_before_end); -ATF_TC_BODY(memcpy_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wmemcpy_heap_before_end); +ATF_TC_BODY(wmemcpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; __stack.__buf = malloc(__bufsz); - memcpy(__stack.__buf, src, __len); + wmemcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memcpy_heap_end); -ATF_TC_BODY(memcpy_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wmemcpy_heap_end); +ATF_TC_BODY(wmemcpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; __stack.__buf = malloc(__bufsz); - memcpy(__stack.__buf, src, __len); + wmemcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memcpy_heap_after_end); -ATF_TC_BODY(memcpy_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wmemcpy_heap_after_end); +ATF_TC_BODY(wmemcpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len + 10]; + wchar_t src[__len + 10]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memcpy(__stack.__buf, src, __len); + wmemcpy(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(mempcpy_before_end); -ATF_TC_BODY(mempcpy_before_end, tc) +ATF_TC_WITHOUT_HEAD(wmempcpy_before_end); +ATF_TC_BODY(wmempcpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; - mempcpy(__stack.__buf, src, __len); + wmempcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(mempcpy_end); -ATF_TC_BODY(mempcpy_end, tc) +ATF_TC_WITHOUT_HEAD(wmempcpy_end); +ATF_TC_BODY(wmempcpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; - mempcpy(__stack.__buf, src, __len); + wmempcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(mempcpy_heap_before_end); -ATF_TC_BODY(mempcpy_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wmempcpy_heap_before_end); +ATF_TC_BODY(wmempcpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; __stack.__buf = malloc(__bufsz); - mempcpy(__stack.__buf, src, __len); + wmempcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(mempcpy_heap_end); -ATF_TC_BODY(mempcpy_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wmempcpy_heap_end); +ATF_TC_BODY(wmempcpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; __stack.__buf = malloc(__bufsz); - mempcpy(__stack.__buf, src, __len); + wmempcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(mempcpy_heap_after_end); -ATF_TC_BODY(mempcpy_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wmempcpy_heap_after_end); +ATF_TC_BODY(wmempcpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len + 10]; + wchar_t src[__len + 10]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - mempcpy(__stack.__buf, src, __len); + wmempcpy(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(memmove_before_end); -ATF_TC_BODY(memmove_before_end, tc) +ATF_TC_WITHOUT_HEAD(wmemmove_before_end); +ATF_TC_BODY(wmemmove_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; - memmove(__stack.__buf, src, __len); + wmemmove(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memmove_end); -ATF_TC_BODY(memmove_end, tc) +ATF_TC_WITHOUT_HEAD(wmemmove_end); +ATF_TC_BODY(wmemmove_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; - memmove(__stack.__buf, src, __len); + wmemmove(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memmove_heap_before_end); -ATF_TC_BODY(memmove_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wmemmove_heap_before_end); +ATF_TC_BODY(wmemmove_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; __stack.__buf = malloc(__bufsz); - memmove(__stack.__buf, src, __len); + wmemmove(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memmove_heap_end); -ATF_TC_BODY(memmove_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wmemmove_heap_end); +ATF_TC_BODY(wmemmove_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len + 10]; + wchar_t src[__len + 10]; __stack.__buf = malloc(__bufsz); - memmove(__stack.__buf, src, __len); + wmemmove(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memmove_heap_after_end); -ATF_TC_BODY(memmove_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wmemmove_heap_after_end); +ATF_TC_BODY(wmemmove_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len + 10]; + wchar_t src[__len + 10]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memmove(__stack.__buf, src, __len); + wmemmove(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(memset_before_end); -ATF_TC_BODY(memset_before_end, tc) +ATF_TC_WITHOUT_HEAD(wmemset_before_end); +ATF_TC_BODY(wmemset_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - memset(__stack.__buf, 0, __len); + wmemset(__stack.__buf, L'0', __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memset_end); -ATF_TC_BODY(memset_end, tc) +ATF_TC_WITHOUT_HEAD(wmemset_end); +ATF_TC_BODY(wmemset_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - memset(__stack.__buf, 0, __len); + wmemset(__stack.__buf, L'0', __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memset_heap_before_end); -ATF_TC_BODY(memset_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wmemset_heap_before_end); +ATF_TC_BODY(wmemset_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); + wmemset(__stack.__buf, L'0', __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memset_heap_end); -ATF_TC_BODY(memset_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wmemset_heap_end); +ATF_TC_BODY(wmemset_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); + wmemset(__stack.__buf, L'0', __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(memset_heap_after_end); -ATF_TC_BODY(memset_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wmemset_heap_after_end); +ATF_TC_BODY(wmemset_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); + wmemset(__stack.__buf, L'0', __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(stpcpy_before_end); -ATF_TC_BODY(stpcpy_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcpcpy_before_end); +ATF_TC_BODY(wcpcpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - stpcpy(__stack.__buf, src); + wcpcpy(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(stpcpy_end); -ATF_TC_BODY(stpcpy_end, tc) +ATF_TC_WITHOUT_HEAD(wcpcpy_end); +ATF_TC_BODY(wcpcpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - stpcpy(__stack.__buf, src); + wcpcpy(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(stpcpy_heap_before_end); -ATF_TC_BODY(stpcpy_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcpcpy_heap_before_end); +ATF_TC_BODY(wcpcpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - stpcpy(__stack.__buf, src); + wcpcpy(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(stpcpy_heap_end); -ATF_TC_BODY(stpcpy_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wcpcpy_heap_end); +ATF_TC_BODY(wcpcpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - stpcpy(__stack.__buf, src); + wcpcpy(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(stpcpy_heap_after_end); -ATF_TC_BODY(stpcpy_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wcpcpy_heap_after_end); +ATF_TC_BODY(wcpcpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len]; + wchar_t src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - stpcpy(__stack.__buf, src); + wcpcpy(__stack.__buf, src); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(stpncpy_before_end); -ATF_TC_BODY(stpncpy_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcpncpy_before_end); +ATF_TC_BODY(wcpncpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - stpncpy(__stack.__buf, src, __len); + wcpncpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(stpncpy_end); -ATF_TC_BODY(stpncpy_end, tc) +ATF_TC_WITHOUT_HEAD(wcpncpy_end); +ATF_TC_BODY(wcpncpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - stpncpy(__stack.__buf, src, __len); + wcpncpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(stpncpy_heap_before_end); -ATF_TC_BODY(stpncpy_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcpncpy_heap_before_end); +ATF_TC_BODY(wcpncpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - stpncpy(__stack.__buf, src, __len); + wcpncpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(stpncpy_heap_end); -ATF_TC_BODY(stpncpy_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wcpncpy_heap_end); +ATF_TC_BODY(wcpncpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - stpncpy(__stack.__buf, src, __len); + wcpncpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(stpncpy_heap_after_end); -ATF_TC_BODY(stpncpy_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wcpncpy_heap_after_end); +ATF_TC_BODY(wcpncpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len]; + wchar_t src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - stpncpy(__stack.__buf, src, __len); + wcpncpy(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(strcat_before_end); -ATF_TC_BODY(strcat_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcscat_before_end); +ATF_TC_BODY(wcscat_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strcat(__stack.__buf, src); + wcscat(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(strcat_end); -ATF_TC_BODY(strcat_end, tc) +ATF_TC_WITHOUT_HEAD(wcscat_end); +ATF_TC_BODY(wcscat_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strcat(__stack.__buf, src); + wcscat(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(strcat_heap_before_end); -ATF_TC_BODY(strcat_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcscat_heap_before_end); +ATF_TC_BODY(wcscat_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strcat(__stack.__buf, src); + wcscat(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(strcat_heap_end); -ATF_TC_BODY(strcat_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wcscat_heap_end); +ATF_TC_BODY(wcscat_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strcat(__stack.__buf, src); + wcscat(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(strcat_heap_after_end); -ATF_TC_BODY(strcat_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wcscat_heap_after_end); +ATF_TC_BODY(wcscat_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len]; + wchar_t src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strcat(__stack.__buf, src); + wcscat(__stack.__buf, src); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(strlcat_before_end); -ATF_TC_BODY(strlcat_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcslcat_before_end); +ATF_TC_BODY(wcslcat_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strlcat(__stack.__buf, src, __len); + wcslcat(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strlcat_end); -ATF_TC_BODY(strlcat_end, tc) +ATF_TC_WITHOUT_HEAD(wcslcat_end); +ATF_TC_BODY(wcslcat_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strlcat(__stack.__buf, src, __len); + wcslcat(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strlcat_heap_before_end); -ATF_TC_BODY(strlcat_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcslcat_heap_before_end); +ATF_TC_BODY(wcslcat_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strlcat(__stack.__buf, src, __len); + wcslcat(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strlcat_heap_end); -ATF_TC_BODY(strlcat_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wcslcat_heap_end); +ATF_TC_BODY(wcslcat_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strlcat(__stack.__buf, src, __len); + wcslcat(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strlcat_heap_after_end); -ATF_TC_BODY(strlcat_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wcslcat_heap_after_end); +ATF_TC_BODY(wcslcat_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len]; + wchar_t src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strlcat(__stack.__buf, src, __len); + wcslcat(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(strncat_before_end); -ATF_TC_BODY(strncat_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcsncat_before_end); +ATF_TC_BODY(wcsncat_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strncat(__stack.__buf, src, __len); + wcsncat(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strncat_end); -ATF_TC_BODY(strncat_end, tc) +ATF_TC_WITHOUT_HEAD(wcsncat_end); +ATF_TC_BODY(wcsncat_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strncat(__stack.__buf, src, __len); + wcsncat(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strncat_heap_before_end); -ATF_TC_BODY(strncat_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcsncat_heap_before_end); +ATF_TC_BODY(wcsncat_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strncat(__stack.__buf, src, __len); + wcsncat(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strncat_heap_end); -ATF_TC_BODY(strncat_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wcsncat_heap_end); +ATF_TC_BODY(wcsncat_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strncat(__stack.__buf, src, __len); + wcsncat(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strncat_heap_after_end); -ATF_TC_BODY(strncat_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wcsncat_heap_after_end); +ATF_TC_BODY(wcsncat_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len]; + wchar_t src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strncat(__stack.__buf, src, __len); + wcsncat(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(strcpy_before_end); -ATF_TC_BODY(strcpy_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcscpy_before_end); +ATF_TC_BODY(wcscpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strcpy(__stack.__buf, src); + wcscpy(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(strcpy_end); -ATF_TC_BODY(strcpy_end, tc) +ATF_TC_WITHOUT_HEAD(wcscpy_end); +ATF_TC_BODY(wcscpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strcpy(__stack.__buf, src); + wcscpy(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(strcpy_heap_before_end); -ATF_TC_BODY(strcpy_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcscpy_heap_before_end); +ATF_TC_BODY(wcscpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strcpy(__stack.__buf, src); + wcscpy(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(strcpy_heap_end); -ATF_TC_BODY(strcpy_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wcscpy_heap_end); +ATF_TC_BODY(wcscpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strcpy(__stack.__buf, src); + wcscpy(__stack.__buf, src); #undef BUF } -ATF_TC_WITHOUT_HEAD(strcpy_heap_after_end); -ATF_TC_BODY(strcpy_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wcscpy_heap_after_end); +ATF_TC_BODY(wcscpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len]; + wchar_t src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strcpy(__stack.__buf, src); + wcscpy(__stack.__buf, src); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(strlcpy_before_end); -ATF_TC_BODY(strlcpy_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcslcpy_before_end); +ATF_TC_BODY(wcslcpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strlcpy(__stack.__buf, src, __len); + wcslcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strlcpy_end); -ATF_TC_BODY(strlcpy_end, tc) +ATF_TC_WITHOUT_HEAD(wcslcpy_end); +ATF_TC_BODY(wcslcpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strlcpy(__stack.__buf, src, __len); + wcslcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strlcpy_heap_before_end); -ATF_TC_BODY(strlcpy_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcslcpy_heap_before_end); +ATF_TC_BODY(wcslcpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strlcpy(__stack.__buf, src, __len); + wcslcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strlcpy_heap_end); -ATF_TC_BODY(strlcpy_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wcslcpy_heap_end); +ATF_TC_BODY(wcslcpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strlcpy(__stack.__buf, src, __len); + wcslcpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strlcpy_heap_after_end); -ATF_TC_BODY(strlcpy_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wcslcpy_heap_after_end); +ATF_TC_BODY(wcslcpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len]; + wchar_t src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strlcpy(__stack.__buf, src, __len); + wcslcpy(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } -ATF_TC_WITHOUT_HEAD(strncpy_before_end); -ATF_TC_BODY(strncpy_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcsncpy_before_end); +ATF_TC_BODY(wcsncpy_before_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strncpy(__stack.__buf, src, __len); + wcsncpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strncpy_end); -ATF_TC_BODY(strncpy_end, tc) +ATF_TC_WITHOUT_HEAD(wcsncpy_end); +ATF_TC_BODY(wcsncpy_end, tc) { #define BUF &__stack.__buf struct { uint8_t padding_l; - unsigned char __buf[42]; + wchar_t __buf[42]; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(__stack.__buf); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strncpy(__stack.__buf, src, __len); + wcsncpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strncpy_heap_before_end); -ATF_TC_BODY(strncpy_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(wcsncpy_heap_before_end); +ATF_TC_BODY(wcsncpy_heap_before_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strncpy(__stack.__buf, src, __len); + wcsncpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strncpy_heap_end); -ATF_TC_BODY(strncpy_heap_end, tc) +ATF_TC_WITHOUT_HEAD(wcsncpy_heap_end); +ATF_TC_BODY(wcsncpy_heap_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42; const size_t __idx __unused = __len - 1; - char src[__len]; + wchar_t src[__len]; __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strncpy(__stack.__buf, src, __len); + wcsncpy(__stack.__buf, src, __len); #undef BUF } -ATF_TC_WITHOUT_HEAD(strncpy_heap_after_end); -ATF_TC_BODY(strncpy_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(wcsncpy_heap_after_end); +ATF_TC_BODY(wcsncpy_heap_after_end, tc) { #define BUF __stack.__buf struct { uint8_t padding_l; - unsigned char * __buf; + wchar_t * __buf; uint8_t padding_r; } __stack; const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42); const size_t __len = 42 + 1; const size_t __idx __unused = __len - 1; pid_t __child; int __status; - char src[__len]; + wchar_t src[__len]; __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); __stack.__buf = malloc(__bufsz); - memset(__stack.__buf, 0, __len); - memset(src, 'A', __len - 1); + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); src[__len - 1] = '\0'; - strncpy(__stack.__buf, src, __len); + wcsncpy(__stack.__buf, src, __len); _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } #undef BUF } ATF_TP_ADD_TCS(tp) { - ATF_TP_ADD_TC(tp, memcpy_before_end); - ATF_TP_ADD_TC(tp, memcpy_end); - ATF_TP_ADD_TC(tp, memcpy_heap_before_end); - ATF_TP_ADD_TC(tp, memcpy_heap_end); - ATF_TP_ADD_TC(tp, memcpy_heap_after_end); - ATF_TP_ADD_TC(tp, mempcpy_before_end); - ATF_TP_ADD_TC(tp, mempcpy_end); - ATF_TP_ADD_TC(tp, mempcpy_heap_before_end); - ATF_TP_ADD_TC(tp, mempcpy_heap_end); - ATF_TP_ADD_TC(tp, mempcpy_heap_after_end); - ATF_TP_ADD_TC(tp, memmove_before_end); - ATF_TP_ADD_TC(tp, memmove_end); - ATF_TP_ADD_TC(tp, memmove_heap_before_end); - ATF_TP_ADD_TC(tp, memmove_heap_end); - ATF_TP_ADD_TC(tp, memmove_heap_after_end); - ATF_TP_ADD_TC(tp, memset_before_end); - ATF_TP_ADD_TC(tp, memset_end); - ATF_TP_ADD_TC(tp, memset_heap_before_end); - ATF_TP_ADD_TC(tp, memset_heap_end); - ATF_TP_ADD_TC(tp, memset_heap_after_end); - ATF_TP_ADD_TC(tp, stpcpy_before_end); - ATF_TP_ADD_TC(tp, stpcpy_end); - ATF_TP_ADD_TC(tp, stpcpy_heap_before_end); - ATF_TP_ADD_TC(tp, stpcpy_heap_end); - ATF_TP_ADD_TC(tp, stpcpy_heap_after_end); - ATF_TP_ADD_TC(tp, stpncpy_before_end); - ATF_TP_ADD_TC(tp, stpncpy_end); - ATF_TP_ADD_TC(tp, stpncpy_heap_before_end); - ATF_TP_ADD_TC(tp, stpncpy_heap_end); - ATF_TP_ADD_TC(tp, stpncpy_heap_after_end); - ATF_TP_ADD_TC(tp, strcat_before_end); - ATF_TP_ADD_TC(tp, strcat_end); - ATF_TP_ADD_TC(tp, strcat_heap_before_end); - ATF_TP_ADD_TC(tp, strcat_heap_end); - ATF_TP_ADD_TC(tp, strcat_heap_after_end); - ATF_TP_ADD_TC(tp, strlcat_before_end); - ATF_TP_ADD_TC(tp, strlcat_end); - ATF_TP_ADD_TC(tp, strlcat_heap_before_end); - ATF_TP_ADD_TC(tp, strlcat_heap_end); - ATF_TP_ADD_TC(tp, strlcat_heap_after_end); - ATF_TP_ADD_TC(tp, strncat_before_end); - ATF_TP_ADD_TC(tp, strncat_end); - ATF_TP_ADD_TC(tp, strncat_heap_before_end); - ATF_TP_ADD_TC(tp, strncat_heap_end); - ATF_TP_ADD_TC(tp, strncat_heap_after_end); - ATF_TP_ADD_TC(tp, strcpy_before_end); - ATF_TP_ADD_TC(tp, strcpy_end); - ATF_TP_ADD_TC(tp, strcpy_heap_before_end); - ATF_TP_ADD_TC(tp, strcpy_heap_end); - ATF_TP_ADD_TC(tp, strcpy_heap_after_end); - ATF_TP_ADD_TC(tp, strlcpy_before_end); - ATF_TP_ADD_TC(tp, strlcpy_end); - ATF_TP_ADD_TC(tp, strlcpy_heap_before_end); - ATF_TP_ADD_TC(tp, strlcpy_heap_end); - ATF_TP_ADD_TC(tp, strlcpy_heap_after_end); - ATF_TP_ADD_TC(tp, strncpy_before_end); - ATF_TP_ADD_TC(tp, strncpy_end); - ATF_TP_ADD_TC(tp, strncpy_heap_before_end); - ATF_TP_ADD_TC(tp, strncpy_heap_end); - ATF_TP_ADD_TC(tp, strncpy_heap_after_end); + ATF_TP_ADD_TC(tp, wmemcpy_before_end); + ATF_TP_ADD_TC(tp, wmemcpy_end); + ATF_TP_ADD_TC(tp, wmemcpy_heap_before_end); + ATF_TP_ADD_TC(tp, wmemcpy_heap_end); + ATF_TP_ADD_TC(tp, wmemcpy_heap_after_end); + ATF_TP_ADD_TC(tp, wmempcpy_before_end); + ATF_TP_ADD_TC(tp, wmempcpy_end); + ATF_TP_ADD_TC(tp, wmempcpy_heap_before_end); + ATF_TP_ADD_TC(tp, wmempcpy_heap_end); + ATF_TP_ADD_TC(tp, wmempcpy_heap_after_end); + ATF_TP_ADD_TC(tp, wmemmove_before_end); + ATF_TP_ADD_TC(tp, wmemmove_end); + ATF_TP_ADD_TC(tp, wmemmove_heap_before_end); + ATF_TP_ADD_TC(tp, wmemmove_heap_end); + ATF_TP_ADD_TC(tp, wmemmove_heap_after_end); + ATF_TP_ADD_TC(tp, wmemset_before_end); + ATF_TP_ADD_TC(tp, wmemset_end); + ATF_TP_ADD_TC(tp, wmemset_heap_before_end); + ATF_TP_ADD_TC(tp, wmemset_heap_end); + ATF_TP_ADD_TC(tp, wmemset_heap_after_end); + ATF_TP_ADD_TC(tp, wcpcpy_before_end); + ATF_TP_ADD_TC(tp, wcpcpy_end); + ATF_TP_ADD_TC(tp, wcpcpy_heap_before_end); + ATF_TP_ADD_TC(tp, wcpcpy_heap_end); + ATF_TP_ADD_TC(tp, wcpcpy_heap_after_end); + ATF_TP_ADD_TC(tp, wcpncpy_before_end); + ATF_TP_ADD_TC(tp, wcpncpy_end); + ATF_TP_ADD_TC(tp, wcpncpy_heap_before_end); + ATF_TP_ADD_TC(tp, wcpncpy_heap_end); + ATF_TP_ADD_TC(tp, wcpncpy_heap_after_end); + ATF_TP_ADD_TC(tp, wcscat_before_end); + ATF_TP_ADD_TC(tp, wcscat_end); + ATF_TP_ADD_TC(tp, wcscat_heap_before_end); + ATF_TP_ADD_TC(tp, wcscat_heap_end); + ATF_TP_ADD_TC(tp, wcscat_heap_after_end); + ATF_TP_ADD_TC(tp, wcslcat_before_end); + ATF_TP_ADD_TC(tp, wcslcat_end); + ATF_TP_ADD_TC(tp, wcslcat_heap_before_end); + ATF_TP_ADD_TC(tp, wcslcat_heap_end); + ATF_TP_ADD_TC(tp, wcslcat_heap_after_end); + ATF_TP_ADD_TC(tp, wcsncat_before_end); + ATF_TP_ADD_TC(tp, wcsncat_end); + ATF_TP_ADD_TC(tp, wcsncat_heap_before_end); + ATF_TP_ADD_TC(tp, wcsncat_heap_end); + ATF_TP_ADD_TC(tp, wcsncat_heap_after_end); + ATF_TP_ADD_TC(tp, wcscpy_before_end); + ATF_TP_ADD_TC(tp, wcscpy_end); + ATF_TP_ADD_TC(tp, wcscpy_heap_before_end); + ATF_TP_ADD_TC(tp, wcscpy_heap_end); + ATF_TP_ADD_TC(tp, wcscpy_heap_after_end); + ATF_TP_ADD_TC(tp, wcslcpy_before_end); + ATF_TP_ADD_TC(tp, wcslcpy_end); + ATF_TP_ADD_TC(tp, wcslcpy_heap_before_end); + ATF_TP_ADD_TC(tp, wcslcpy_heap_end); + ATF_TP_ADD_TC(tp, wcslcpy_heap_after_end); + ATF_TP_ADD_TC(tp, wcsncpy_before_end); + ATF_TP_ADD_TC(tp, wcsncpy_end); + ATF_TP_ADD_TC(tp, wcsncpy_heap_before_end); + ATF_TP_ADD_TC(tp, wcsncpy_heap_end); + ATF_TP_ADD_TC(tp, wcsncpy_heap_after_end); return (atf_no_error()); } diff --git a/lib/libc/tests/secure/generate-fortify-tests.lua b/lib/libc/tests/secure/generate-fortify-tests.lua index b559fbded070..1807cbf477e9 100755 --- a/lib/libc/tests/secure/generate-fortify-tests.lua +++ b/lib/libc/tests/secure/generate-fortify-tests.lua @@ -1,1031 +1,1181 @@ #!/usr/libexec/flua -- -- SPDX-License-Identifier: BSD-2-Clause -- -- Copyright (c) 2024, Klara, Inc. -- -- 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. -- -- THEORY OF OPERATION -- -- generate-fortify-tests.lua is intended to test fortified functions as found -- mostly in the various headers in /usr/include/ssp. Each fortified function -- gets three basic tests: -- -- 1. Write just before the end of the buffer, -- 2. Write right at the end of the buffer, -- 3. Write just after the end of the buffer. -- -- Each test is actually generated twice: once with a buffer on the stack, and -- again with a buffer on the heap, to confirm that __builtin_object_size(3) can -- deduce the buffer size in both scenarios. The tests work by setting up the -- stack with our buffer (and some padding on either side to avoid tripping any -- other stack or memory protection), doing any initialization as described by -- the test definition, then calling the fortified function with the buffer as -- outlined by the test definition. -- -- For the 'before' and 'at' the end tests, we're ensuring that valid writes -- that are on the verge of being invalid aren't accidentally being detected as -- invalid. -- -- The 'after' test is the one that actually tests the functional benefit of -- _FORTIFY_SOURCE by violating a boundary that should trigger an abort. As -- such, this test differs more from the other two in that it has to fork() off -- the fortified function call so that we can monitor for a SIGABRT and -- pass/fail the test at function end appropriately. -- Some tests, like the FD_*() macros, may define these differently. For -- instance, for fd sets we're varying the index we pass and not using arbitrary -- buffers. Other tests that don't use the length in any way may physically -- vary the buffer size for each test case when we'd typically vary the length -- we're requesting a write for. local includes = { "sys/param.h", "sys/resource.h", "sys/time.h", "sys/wait.h", "dirent.h", "errno.h", "fcntl.h", "limits.h", "poll.h", "signal.h", "stdio.h", "stdlib.h", "string.h", "strings.h", "sysexits.h", "unistd.h", + "wchar.h", "atf-c.h", } local tests_added = {} -- Some of these will need to be excluded because clang sees the wrong size when -- an array is embedded inside a struct, we'll get something that looks more -- like __builtin_object_size(ptr, 0) than it does the correct -- __builtin_object_size(ptr, 1) (i.e., includes the padding after). This is -- almost certainly a bug in llvm. local function excludes_stack_overflow(disposition, is_heap) return (not is_heap) and disposition > 0 end local poll_init = [[ for (size_t i = 0; i < howmany(__bufsz, sizeof(struct pollfd)); i++) { __stack.__buf[i].fd = -1; } ]] local printf_stackvars = "\tchar srcvar[__len + 10];\n" local printf_init = [[ memset(srcvar, 'A', sizeof(srcvar) - 1); srcvar[sizeof(srcvar) - 1] = '\0'; ]] local stdio_init = [[ replace_stdin(); ]] local string_stackvars = "\tchar src[__len];\n" local string_init = [[ memset(__stack.__buf, 0, __len); memset(src, 'A', __len - 1); src[__len - 1] = '\0'; ]] +local wstring_stackvars = "\twchar_t src[__len];\n" +local wstring_init = [[ + wmemset(__stack.__buf, 0, __len); + wmemset(src, 'A', __len - 1); + src[__len - 1] = '\0'; +]] + -- Each test entry describes how to test a given function. We need to know how -- to construct the buffer, we need to know the argument set we're dealing with, -- and we need to know what we're passing to each argument. We could be passing -- fixed values, or we could be passing the __buf under test. -- -- definition: -- func: name of the function under test to call -- bufsize: size of buffer to generate, defaults to 42 -- buftype: type of buffer to generate, defaults to unsigned char[] -- arguments: __buf, __len, or the name of a variable placed on the stack -- exclude: a function(disposition, is_heap) that returns true if this combo -- should be excluded. -- stackvars: extra variables to be placed on the stack, should be a string -- optionally formatted with tabs and newlines -- init: extra code to inject just before the function call for initialization -- of the buffer or any of the above-added stackvars; also a string -- uses_len: bool-ish, necessary if arguments doesn't include either __idx or -- or __len so that the test generator doesn't try to vary the size of the -- buffer instead of just manipulating __idx/__len to try and induce an -- overflow. -- -- Most tests will just use the default bufsize/buftype, but under some -- circumstances it's useful to use a different type (e.g., for alignment -- requirements). local all_tests = { poll = { -- { func = "poll", bufsize = "4", buftype = "struct pollfd[]", arguments = { "__buf", "__len", "0", }, init = poll_init, }, { func = "ppoll", bufsize = "4", buftype = "struct pollfd[]", arguments = { "__buf", "__len", "&tv", "NULL", }, stackvars = "\tstruct timespec tv = { 0 };\n", init = poll_init, }, }, stdio = { -- { func = "ctermid", bufsize = "L_ctermid", arguments = { "__buf", }, exclude = excludes_stack_overflow, }, { func = "ctermid_r", bufsize = "L_ctermid", arguments = { "__buf", }, exclude = excludes_stack_overflow, }, { func = "fread", arguments = { "__buf", "__len", "1", "stdin", }, exclude = excludes_stack_overflow, init = stdio_init, }, { func = "fread_unlocked", arguments = { "__buf", "__len", "1", "stdin", }, exclude = excludes_stack_overflow, init = stdio_init, }, { func = "gets_s", arguments = { "__buf", "__len", }, exclude = excludes_stack_overflow, init = stdio_init, }, { func = "sprintf", arguments = { "__buf", "\"%.*s\"", "(int)__len - 1", -- - 1 for NUL terminator "srcvar", }, exclude = excludes_stack_overflow, stackvars = printf_stackvars, init = printf_init, }, { func = "snprintf", arguments = { "__buf", "__len", "\"%.*s\"", "(int)__len - 1", -- - 1 for NUL terminator "srcvar", }, exclude = excludes_stack_overflow, stackvars = printf_stackvars, init = printf_init, }, { func = "tmpnam", bufsize = "L_tmpnam", arguments = { "__buf", }, exclude = excludes_stack_overflow, }, { func = "fgets", arguments = { "__buf", "__len", "fp", }, exclude = excludes_stack_overflow, stackvars = "\tFILE *fp;\n", init = [[ fp = new_fp(__len); ]], }, }, stdlib = { -- { func = "arc4random_buf", arguments = { "__buf", "__len", }, exclude = excludes_stack_overflow, }, { func = "realpath", bufsize = "PATH_MAX", arguments = { "\".\"", "__buf", }, exclude = excludes_stack_overflow, }, }, string = { -- { func = "memcpy", arguments = { "__buf", "src", "__len", }, exclude = excludes_stack_overflow, stackvars = "\tchar src[__len + 10];\n", }, { func = "mempcpy", arguments = { "__buf", "src", "__len", }, exclude = excludes_stack_overflow, stackvars = "\tchar src[__len + 10];\n", }, { func = "memmove", arguments = { "__buf", "src", "__len", }, exclude = excludes_stack_overflow, stackvars = "\tchar src[__len + 10];\n", }, { func = "memset", arguments = { "__buf", "0", "__len", }, exclude = excludes_stack_overflow, }, { func = "stpcpy", arguments = { "__buf", "src", }, exclude = excludes_stack_overflow, stackvars = string_stackvars, init = string_init, uses_len = true, }, { func = "stpncpy", arguments = { "__buf", "src", "__len", }, exclude = excludes_stack_overflow, stackvars = string_stackvars, init = string_init, }, { func = "strcat", arguments = { "__buf", "src", }, exclude = excludes_stack_overflow, stackvars = string_stackvars, init = string_init, uses_len = true, }, { func = "strlcat", arguments = { "__buf", "src", "__len", }, exclude = excludes_stack_overflow, stackvars = string_stackvars, init = string_init, }, { func = "strncat", arguments = { "__buf", "src", "__len", }, exclude = excludes_stack_overflow, stackvars = string_stackvars, init = string_init, }, { func = "strcpy", arguments = { "__buf", "src", }, exclude = excludes_stack_overflow, stackvars = string_stackvars, init = string_init, uses_len = true, }, { func = "strlcpy", arguments = { "__buf", "src", "__len", }, exclude = excludes_stack_overflow, stackvars = string_stackvars, init = string_init, }, { func = "strncpy", arguments = { "__buf", "src", "__len", }, exclude = excludes_stack_overflow, stackvars = string_stackvars, init = string_init, }, }, strings = { -- { func = "bcopy", arguments = { "src", "__buf", "__len", }, exclude = excludes_stack_overflow, stackvars = "\tchar src[__len + 10];\n", }, { func = "bzero", arguments = { "__buf", "__len", }, exclude = excludes_stack_overflow, }, { func = "explicit_bzero", arguments = { "__buf", "__len", }, exclude = excludes_stack_overflow, }, }, unistd = { -- { func = "getcwd", bufsize = "8", arguments = { "__buf", "__len", }, exclude = excludes_stack_overflow, }, { func = "getgrouplist", bufsize = "4", buftype = "gid_t[]", arguments = { "\"root\"", "0", "__buf", "&intlen", }, exclude = excludes_stack_overflow, stackvars = "\tint intlen = (int)__len;\n", uses_len = true, }, { func = "getgroups", bufsize = "4", buftype = "gid_t[]", arguments = { "__len", "__buf", }, exclude = excludes_stack_overflow, }, { func = "getloginclass", arguments = { "__buf", "__len", }, exclude = excludes_stack_overflow, }, { func = "pread", bufsize = "41", arguments = { "fd", "__buf", "__len", "0", }, exclude = excludes_stack_overflow, stackvars = "\tint fd;\n", init = [[ fd = new_tmpfile(); /* Cannot fail */ ]], }, { func = "read", bufsize = "41", arguments = { "fd", "__buf", "__len", }, exclude = excludes_stack_overflow, stackvars = "\tint fd;\n", init = [[ fd = new_tmpfile(); /* Cannot fail */ ]], }, { func = "readlink", arguments = { "path", "__buf", "__len", }, exclude = excludes_stack_overflow, stackvars = "\tconst char *path;\n", init = [[ path = new_symlink(__len); /* Cannot fail */ ]], }, { func = "readlinkat", arguments = { "AT_FDCWD", "path", "__buf", "__len", }, exclude = excludes_stack_overflow, stackvars = "\tconst char *path;\n", init = [[ path = new_symlink(__len); /* Cannot fail */ ]], }, { func = "getdomainname", bufsize = "4", arguments = { "__buf", "__len", }, exclude = excludes_stack_overflow, stackvars = "\tchar sysdomain[256];\n", early_init = [[ (void)getdomainname(sysdomain, __len); if (strlen(sysdomain) <= __len) atf_tc_skip("domain name too short for testing"); ]] }, { func = "getentropy", arguments = { "__buf", "__len", }, exclude = excludes_stack_overflow, }, { func = "gethostname", bufsize = "4", arguments = { "__buf", "__len", }, exclude = excludes_stack_overflow, stackvars = [[ char syshost[256]; int error; ]], early_init = [[ error = gethostname(syshost, __len); if (error != 0 || strlen(syshost) <= __len) atf_tc_skip("hostname too short for testing"); ]] }, { func = "getlogin_r", bufsize = "MAXLOGNAME + 1", arguments = { "__buf", "__len", }, exclude = excludes_stack_overflow, }, { func = "ttyname_r", arguments = { "fd", "__buf", "__len", }, exclude = excludes_stack_overflow, stackvars = "\tint fd;\n", early_init = [[ fd = STDIN_FILENO; if (!isatty(fd)) atf_tc_skip("stdin is not an fd"); ]] }, }, + wchar = { + -- + { + func = "wmemcpy", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + "__len", + }, + exclude = excludes_stack_overflow, + stackvars = "\twchar_t src[__len + 10];\n", + }, + { + func = "wmempcpy", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + "__len", + }, + exclude = excludes_stack_overflow, + stackvars = "\twchar_t src[__len + 10];\n", + }, + { + func = "wmemmove", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + "__len", + }, + exclude = excludes_stack_overflow, + stackvars = "\twchar_t src[__len + 10];\n", + }, + { + func = "wmemset", + buftype = "wchar_t[]", + arguments = { + "__buf", + "L'0'", + "__len", + }, + exclude = excludes_stack_overflow, + }, + { + func = "wcpcpy", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + }, + exclude = excludes_stack_overflow, + stackvars = wstring_stackvars, + init = wstring_init, + uses_len = true, + }, + { + func = "wcpncpy", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + "__len", + }, + exclude = excludes_stack_overflow, + stackvars = wstring_stackvars, + init = wstring_init, + }, + { + func = "wcscat", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + }, + exclude = excludes_stack_overflow, + stackvars = wstring_stackvars, + init = wstring_init, + uses_len = true, + }, + { + func = "wcslcat", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + "__len", + }, + exclude = excludes_stack_overflow, + stackvars = wstring_stackvars, + init = wstring_init, + }, + { + func = "wcsncat", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + "__len", + }, + exclude = excludes_stack_overflow, + stackvars = wstring_stackvars, + init = wstring_init, + }, + { + func = "wcscpy", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + }, + exclude = excludes_stack_overflow, + stackvars = wstring_stackvars, + init = wstring_init, + uses_len = true, + }, + { + func = "wcslcpy", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + "__len", + }, + exclude = excludes_stack_overflow, + stackvars = wstring_stackvars, + init = wstring_init, + }, + { + func = "wcsncpy", + buftype = "wchar_t[]", + arguments = { + "__buf", + "src", + "__len", + }, + exclude = excludes_stack_overflow, + stackvars = wstring_stackvars, + init = wstring_init, + }, + }, } local function write_test_boilerplate(fh, name, body) fh:write("ATF_TC_WITHOUT_HEAD(" .. name .. ");\n") fh:write("ATF_TC_BODY(" .. name .. ", tc)\n") fh:write("{\n" .. body .. "\n}\n\n") return name end local function generate_test_name(func, variant, disposition, heap) local basename = func if variant then basename = basename .. "_" .. variant end if heap then basename = basename .. "_heap" end if disposition < 0 then return basename .. "_before_end" elseif disposition == 0 then return basename .. "_end" else return basename .. "_after_end" end end local function array_type(buftype) if not buftype:match("%[%]") then return nil end return buftype:gsub("%[%]", "") end local function configurable(def, idx) local cfgitem = def[idx] if not cfgitem then return nil end if type(cfgitem) == "function" then return cfgitem() end return cfgitem end local function generate_stackframe(buftype, bufsize, disposition, heap, def) local function len_offset(inverted, disposition) -- Tests that don't use __len in their arguments may use an -- inverted sense because we can't just specify a length that -- would induce an access just after the end. Instead, we have -- to manipulate the buffer size to be too short so that the -- function under test would write one too many. if disposition < 0 then return ((inverted and " + ") or " - ") .. "1" elseif disposition == 0 then return "" else return ((inverted and " - ") or " + ") .. "1" end end local function test_uses_len(def) if def.uses_len then return true end for _, arg in ipairs(def.arguments) do if arg:match("__len") or arg:match("__idx") then return true end end return false end -- This is perhaps a little convoluted, but we toss the buffer into a -- struct on the stack to guarantee that we have at least one valid -- byte on either side of the buffer -- a measure to make sure that -- we're tripping _FORTIFY_SOURCE specifically in the buffer + 1 case, -- rather than some other stack or memory protection. local vars = "\tstruct {\n" vars = vars .. "\t\tuint8_t padding_l;\n" local uses_len = test_uses_len(def) local bufsize_offset = len_offset(not uses_len, disposition) local buftype_elem = array_type(buftype) local size_expr = bufsize if not uses_len then -- If the length isn't in use, we have to vary the buffer size -- since the fortified function likely has some internal size -- constraint that it's supposed to be checking. size_expr = size_expr .. bufsize_offset end if not heap and buftype_elem then -- Array type: size goes after identifier vars = vars .. "\t\t" .. buftype_elem .. " __buf[" .. size_expr .. "];\n" else local basic_type = buftype_elem or buftype -- Heap tests obviously just put a pointer on the stack that -- points to our new allocation, but we leave it in the padded -- struct just to simplify our generator. if heap then basic_type = basic_type .. " *" end vars = vars .. "\t\t" .. basic_type .. " __buf;\n" end -- padding_r is our just-past-the-end padding that we use to make sure -- that there's a valid portion after the buffer that isn't being -- included in our function calls. If we didn't have it, then we'd have -- a hard time feeling confident that an abort on the just-after tests -- isn't maybe from some other memory or stack protection. vars = vars .. "\t\tuint8_t padding_r;\n" vars = vars .. "\t} __stack;\n" -- Not all tests will use __bufsz, but some do for, e.g., clearing -- memory.. vars = vars .. "\tconst size_t __bufsz __unused = " if heap then local scalar = 1 if buftype_elem then scalar = size_expr end vars = vars .. "sizeof(*__stack.__buf) * (" .. scalar .. ");\n" else vars = vars .. "sizeof(__stack.__buf);\n" end vars = vars .. "\tconst size_t __len = " .. bufsize .. bufsize_offset .. ";\n" vars = vars .. "\tconst size_t __idx __unused = __len - 1;\n" -- For overflow testing, we need to fork() because we're expecting the -- test to ultimately abort()/_exit(). Then we can collect the exit -- status and report appropriately. if disposition > 0 then vars = vars .. "\tpid_t __child;\n" vars = vars .. "\tint __status;\n" end -- Any other stackvars defined by the test get placed after everything -- else. vars = vars .. (configurable(def, "stackvars") or "") return vars end local function write_test(fh, func, disposition, heap, def) local testname = generate_test_name(func, def.variant, disposition, heap) local buftype = def.buftype or "unsigned char[]" local bufsize = def.bufsize or 42 local body = "" if def.exclude and def.exclude(disposition, heap) then return end local function need_addr(buftype) return not (buftype:match("%[%]") or buftype:match("%*")) end if heap then body = body .. "#define BUF __stack.__buf\n" else body = body .. "#define BUF &__stack.__buf\n" end -- Setup the buffer body = body .. generate_stackframe(buftype, bufsize, disposition, heap, def) .. "\n" -- Any early initialization goes before we would fork for the just-after -- tests, because they may want to skip the test based on some criteria -- and we can't propagate that up very easily once we're forked. local early_init = configurable(def, "early_init") body = body .. (early_init or "") if early_init then body = body .. "\n" end -- Fork off, iff we're testing some access past the end of the buffer. if disposition > 0 then body = body .. [[ __child = fork(); ATF_REQUIRE(__child >= 0); if (__child > 0) goto monitor; /* Child */ disable_coredumps(); ]] end local bufvar = "__stack.__buf" if heap then -- Buffer needs to be initialized because it's a heap allocation. body = body .. "\t" .. bufvar .. " = malloc(__bufsz);\n" end -- Non-early init happens just after the fork in the child, not the -- monitor. This is used to setup any other buffers we may need, for -- instance. local extra_init = configurable(def, "init") body = body .. (extra_init or "") if heap or extra_init then body = body .. "\n" end -- Setup the function call with arguments as described in the test -- definition. body = body .. "\t" .. func .. "(" for idx, arg in ipairs(def.arguments) do if idx > 1 then body = body .. ", " end if arg == "__buf" then if not heap and need_addr(buftype) then body = body .. "&" end body = body .. bufvar else local argname = arg if def.value_of then argname = argname or def.value_of(arg) end body = body .. argname end end body = body .. ");\n" -- Monitor stuff follows, for OOB access. if disposition <= 0 then goto skip end body = body .. [[ _exit(EX_SOFTWARE); /* Should have aborted. */ monitor: while (waitpid(__child, &__status, 0) != __child) { ATF_REQUIRE_EQ(EINTR, errno); } if (!WIFSIGNALED(__status)) { switch (WEXITSTATUS(__status)) { case EX_SOFTWARE: atf_tc_fail("FORTIFY_SOURCE failed to abort"); break; case EX_OSERR: atf_tc_fail("setrlimit(2) failed"); break; default: atf_tc_fail("child exited with status %d", WEXITSTATUS(__status)); } } else { ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status)); } ]] ::skip:: body = body .. "#undef BUF\n" return write_test_boilerplate(fh, testname, body) end -- main() local tests local tcat = assert(arg[1], "usage: generate-fortify-tests.lua ") for k, defs in pairs(all_tests) do if k == tcat then tests = defs break end end assert(tests, "category " .. tcat .. " not found") local fh = io.stdout fh:write("/* @" .. "generated" .. " by `generate-fortify-tests.lua \"" .. tcat .. "\"` */\n\n") fh:write("#define _FORTIFY_SOURCE 2\n") fh:write("#define TMPFILE_SIZE (1024 * 32)\n") fh:write("\n") for _, inc in ipairs(includes) do fh:write("#include <" .. inc .. ">\n") end fh:write([[ static FILE * __unused new_fp(size_t __len) { static char fpbuf[LINE_MAX]; FILE *fp; ATF_REQUIRE(__len <= sizeof(fpbuf)); memset(fpbuf, 'A', sizeof(fpbuf) - 1); fpbuf[sizeof(fpbuf) - 1] = '\0'; fp = fmemopen(fpbuf, sizeof(fpbuf), "rb"); ATF_REQUIRE(fp != NULL); return (fp); } /* * Create a new symlink to use for readlink(2) style tests, we'll just use a * random target name to have something interesting to look at. */ static const char * __unused new_symlink(size_t __len) { static const char linkname[] = "link"; char target[MAXNAMLEN]; int error; ATF_REQUIRE(__len <= sizeof(target)); arc4random_buf(target, sizeof(target)); error = unlink(linkname); ATF_REQUIRE(error == 0 || errno == ENOENT); error = symlink(target, linkname); ATF_REQUIRE(error == 0); return (linkname); } /* * Constructs a tmpfile that we can use for testing read(2) and friends. */ static int __unused new_tmpfile(void) { char buf[1024]; ssize_t rv; size_t written; int fd; fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644); ATF_REQUIRE(fd >= 0); written = 0; while (written < TMPFILE_SIZE) { rv = write(fd, buf, sizeof(buf)); ATF_REQUIRE(rv > 0); written += rv; } ATF_REQUIRE_EQ(0, lseek(fd, 0, SEEK_SET)); return (fd); } static void disable_coredumps(void) { struct rlimit rl = { 0 }; if (setrlimit(RLIMIT_CORE, &rl) == -1) _exit(EX_OSERR); } /* * Replaces stdin with a file that we can actually read from, for tests where * we want a FILE * or fd that we can get data from. */ static void __unused replace_stdin(void) { int fd; fd = new_tmpfile(); (void)dup2(fd, STDIN_FILENO); if (fd != STDIN_FILENO) close(fd); } ]]) for _, def in pairs(tests) do local func = def.func local function write_tests(heap) -- Dispositions here are relative to the buffer size prescribed -- by the test definition. local dispositions = def.dispositions or { -1, 0, 1 } for _, disposition in ipairs(dispositions) do tests_added[#tests_added + 1] = write_test(fh, func, disposition, heap, def) end end write_tests(false) write_tests(true) end fh:write("ATF_TP_ADD_TCS(tp)\n") fh:write("{\n") for idx = 1, #tests_added do fh:write("\tATF_TP_ADD_TC(tp, " .. tests_added[idx] .. ");\n") end fh:write("\treturn (atf_no_error());\n") fh:write("}\n")