diff --git a/include/ssp/Makefile b/include/ssp/Makefile --- a/include/ssp/Makefile +++ b/include/ssp/Makefile @@ -1,4 +1,5 @@ -INCS= poll.h ssp.h stdio.h stdlib.h string.h strings.h unistd.h wchar.h +INCS= poll.h random.h ssp.h stdio.h stdlib.h string.h strings.h unistd.h +INCS+= wchar.h INCSDIR= ${INCLUDEDIR}/ssp .include diff --git a/include/ssp/random.h b/include/ssp/random.h new file mode 100644 --- /dev/null +++ b/include/ssp/random.h @@ -0,0 +1,43 @@ +/*- + * + * 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_RANDOM_H_ +#define _SSP_RANDOM_H_ + +#include + +#if __SSP_FORTIFY_LEVEL > 0 + +__BEGIN_DECLS + +__ssp_redirect(ssize_t, getrandom, (void *__buf, size_t __len, + unsigned int __flags), (__buf, __len, __flags)); + +__END_DECLS + +#endif /* __SSP_FORTIFY_LEVEL > 0 */ +#endif /* _SSP_RANDOM_H_ */ diff --git a/lib/libc/tests/secure/Makefile b/lib/libc/tests/secure/Makefile --- a/lib/libc/tests/secure/Makefile +++ b/lib/libc/tests/secure/Makefile @@ -3,6 +3,10 @@ TESTSDIR:= ${TESTSBASE}/${RELDIR:C/libc\/tests/libc/} +# sys/ headers +FORTIFY_TCATS+= random + +# non-sys/ headers FORTIFY_TCATS+= poll FORTIFY_TCATS+= stdlib FORTIFY_TCATS+= stdio diff --git a/lib/libc/tests/secure/fortify_poll_test.c b/lib/libc/tests/secure/fortify_poll_test.c --- a/lib/libc/tests/secure/fortify_poll_test.c +++ b/lib/libc/tests/secure/fortify_poll_test.c @@ -4,6 +4,7 @@ #define TMPFILE_SIZE (1024 * 32) #include +#include #include #include #include diff --git a/lib/libc/tests/secure/fortify_stdlib_test.c b/lib/libc/tests/secure/fortify_random_test.c copy from lib/libc/tests/secure/fortify_stdlib_test.c copy to lib/libc/tests/secure/fortify_random_test.c --- a/lib/libc/tests/secure/fortify_stdlib_test.c +++ b/lib/libc/tests/secure/fortify_random_test.c @@ -4,6 +4,7 @@ #define TMPFILE_SIZE (1024 * 32) #include +#include #include #include #include @@ -112,8 +113,8 @@ close(fd); } -ATF_TC_WITHOUT_HEAD(arc4random_buf_before_end); -ATF_TC_BODY(arc4random_buf_before_end, tc) +ATF_TC_WITHOUT_HEAD(getrandom_before_end); +ATF_TC_BODY(getrandom_before_end, tc) { #define BUF &__stack.__buf struct { @@ -125,13 +126,13 @@ const size_t __len = 42 - 1; const size_t __idx __unused = __len - 1; - arc4random_buf(__stack.__buf, __len); + getrandom(__stack.__buf, __len, 0); #undef BUF } -ATF_TC_WITHOUT_HEAD(arc4random_buf_end); -ATF_TC_BODY(arc4random_buf_end, tc) +ATF_TC_WITHOUT_HEAD(getrandom_end); +ATF_TC_BODY(getrandom_end, tc) { #define BUF &__stack.__buf struct { @@ -143,13 +144,13 @@ const size_t __len = 42; const size_t __idx __unused = __len - 1; - arc4random_buf(__stack.__buf, __len); + getrandom(__stack.__buf, __len, 0); #undef BUF } -ATF_TC_WITHOUT_HEAD(arc4random_buf_heap_before_end); -ATF_TC_BODY(arc4random_buf_heap_before_end, tc) +ATF_TC_WITHOUT_HEAD(getrandom_heap_before_end); +ATF_TC_BODY(getrandom_heap_before_end, tc) { #define BUF __stack.__buf struct { @@ -163,13 +164,13 @@ __stack.__buf = malloc(__bufsz); - arc4random_buf(__stack.__buf, __len); + getrandom(__stack.__buf, __len, 0); #undef BUF } -ATF_TC_WITHOUT_HEAD(arc4random_buf_heap_end); -ATF_TC_BODY(arc4random_buf_heap_end, tc) +ATF_TC_WITHOUT_HEAD(getrandom_heap_end); +ATF_TC_BODY(getrandom_heap_end, tc) { #define BUF __stack.__buf struct { @@ -183,13 +184,13 @@ __stack.__buf = malloc(__bufsz); - arc4random_buf(__stack.__buf, __len); + getrandom(__stack.__buf, __len, 0); #undef BUF } -ATF_TC_WITHOUT_HEAD(arc4random_buf_heap_after_end); -ATF_TC_BODY(arc4random_buf_heap_after_end, tc) +ATF_TC_WITHOUT_HEAD(getrandom_heap_after_end); +ATF_TC_BODY(getrandom_heap_after_end, tc) { #define BUF __stack.__buf struct { @@ -212,121 +213,7 @@ disable_coredumps(); __stack.__buf = malloc(__bufsz); - arc4random_buf(__stack.__buf, __len); - _exit(1); /* Should have aborted. */ - -monitor: - while (waitpid(__child, &__status, 0) != __child) { - ATF_REQUIRE_EQ(EINTR, errno); - } - - ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status); - 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); + getrandom(__stack.__buf, __len, 0); _exit(1); /* Should have aborted. */ monitor: @@ -342,15 +229,10 @@ 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); + ATF_TP_ADD_TC(tp, getrandom_before_end); + ATF_TP_ADD_TC(tp, getrandom_end); + ATF_TP_ADD_TC(tp, getrandom_heap_before_end); + ATF_TP_ADD_TC(tp, getrandom_heap_end); + ATF_TP_ADD_TC(tp, getrandom_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 --- a/lib/libc/tests/secure/fortify_stdio_test.c +++ b/lib/libc/tests/secure/fortify_stdio_test.c @@ -4,6 +4,7 @@ #define TMPFILE_SIZE (1024 * 32) #include +#include #include #include #include diff --git a/lib/libc/tests/secure/fortify_stdlib_test.c b/lib/libc/tests/secure/fortify_stdlib_test.c --- a/lib/libc/tests/secure/fortify_stdlib_test.c +++ b/lib/libc/tests/secure/fortify_stdlib_test.c @@ -4,6 +4,7 @@ #define TMPFILE_SIZE (1024 * 32) #include +#include #include #include #include diff --git a/lib/libc/tests/secure/fortify_string_test.c b/lib/libc/tests/secure/fortify_string_test.c --- a/lib/libc/tests/secure/fortify_string_test.c +++ b/lib/libc/tests/secure/fortify_string_test.c @@ -4,6 +4,7 @@ #define TMPFILE_SIZE (1024 * 32) #include +#include #include #include #include diff --git a/lib/libc/tests/secure/fortify_strings_test.c b/lib/libc/tests/secure/fortify_strings_test.c --- a/lib/libc/tests/secure/fortify_strings_test.c +++ b/lib/libc/tests/secure/fortify_strings_test.c @@ -4,6 +4,7 @@ #define TMPFILE_SIZE (1024 * 32) #include +#include #include #include #include diff --git a/lib/libc/tests/secure/fortify_unistd_test.c b/lib/libc/tests/secure/fortify_unistd_test.c --- a/lib/libc/tests/secure/fortify_unistd_test.c +++ b/lib/libc/tests/secure/fortify_unistd_test.c @@ -4,6 +4,7 @@ #define TMPFILE_SIZE (1024 * 32) #include +#include #include #include #include diff --git a/lib/libc/tests/secure/fortify_wchar_test.c b/lib/libc/tests/secure/fortify_wchar_test.c --- a/lib/libc/tests/secure/fortify_wchar_test.c +++ b/lib/libc/tests/secure/fortify_wchar_test.c @@ -4,6 +4,7 @@ #define TMPFILE_SIZE (1024 * 32) #include +#include #include #include #include diff --git a/lib/libc/tests/secure/generate-fortify-tests.lua b/lib/libc/tests/secure/generate-fortify-tests.lua --- a/lib/libc/tests/secure/generate-fortify-tests.lua +++ b/lib/libc/tests/secure/generate-fortify-tests.lua @@ -28,6 +28,7 @@ local includes = { "sys/param.h", + "sys/random.h", "sys/resource.h", "sys/time.h", "sys/wait.h", @@ -112,6 +113,18 @@ -- circumstances it's useful to use a different type (e.g., for alignment -- requirements). local all_tests = { + random = { + -- + { + func = "getrandom", + arguments = { + "__buf", + "__len", + "0", + }, + exclude = excludes_stack_overflow, + }, + }, poll = { -- { diff --git a/sys/sys/random.h b/sys/sys/random.h --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -161,6 +161,10 @@ #define GRND_RANDOM 0x2 #define GRND_INSECURE 0x4 +#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 +#include +#endif + __BEGIN_DECLS ssize_t getrandom(void *buf, size_t buflen, unsigned int flags); __END_DECLS