The branch main has been updated by kevans:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=020d003c86367bb5751b6d58fb58611242802c7f

commit 020d003c86367bb5751b6d58fb58611242802c7f
Author:     Kyle Evans <[email protected]>
AuthorDate: 2024-07-13 05:16:10 +0000
Commit:     Kyle Evans <[email protected]>
CommitDate: 2024-07-13 05:16:23 +0000

    libc: tests: add testing infrastructure for _FORTIFY_SOURCE
    
    The _FORTIFY_SOURCE tests will be generated by a lua script to avoid a
    lot of redundancy in writing these tests.  For each function that we're
    fortifying, the plan is to test at least the following three scenarios:
    
     - Writing up to one byte before the end of the buffer,
     - Writing up to the end of the buffer,
     - Writing one byte past the end of the buffer
    
    The buffer is shoved into a struct on the stack to guarantee a stack
    layout in which we have a valid byte after the buffer so that level 2
    fortification will trip and we can have confidence that it wasn't some
    other stack/memory protection instead.
    
    The generated tests are divided roughly into which header we're
    attributing them to so that we can parallelize the build -- the full set
    is a bit over 9000 lines of C and takes 11s to build on the hardware
    that I'm testing on if it's a single monolothic file.
    
    Reviewed by:    markj
    Sponsored by:   Klara, Inc.
    Sponsored by:   Stormshield
    Differential Revision:  https://reviews.freebsd.org/D45678
---
 etc/mtree/BSD.tests.dist                         |    2 +
 lib/libc/tests/Makefile                          |    1 +
 lib/libc/tests/secure/Makefile                   |   20 +
 lib/libc/tests/secure/fortify_stdio_test.c       |  383 ++++++
 lib/libc/tests/secure/fortify_string_test.c      | 1415 ++++++++++++++++++++++
 lib/libc/tests/secure/fortify_strings_test.c     |  354 ++++++
 lib/libc/tests/secure/fortify_unistd_test.c      |  505 ++++++++
 lib/libc/tests/secure/generate-fortify-tests.lua |  706 +++++++++++
 8 files changed, 3386 insertions(+)

diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist
index 375e4900b5d5..bd9edc786f17 100644
--- a/etc/mtree/BSD.tests.dist
+++ b/etc/mtree/BSD.tests.dist
@@ -372,6 +372,8 @@
             ..
             rpc
             ..
+            secure
+            ..
             setjmp
             ..
             ssp
diff --git a/lib/libc/tests/Makefile b/lib/libc/tests/Makefile
index 7b262ea646fb..7f72fb619004 100644
--- a/lib/libc/tests/Makefile
+++ b/lib/libc/tests/Makefile
@@ -13,6 +13,7 @@ TESTS_SUBDIRS+=       nss
 TESTS_SUBDIRS+=        regex
 TESTS_SUBDIRS+=        resolv
 TESTS_SUBDIRS+=        rpc
+TESTS_SUBDIRS+=        secure
 TESTS_SUBDIRS+=        setjmp
 TESTS_SUBDIRS+=        stdio
 TESTS_SUBDIRS+=        stdlib
diff --git a/lib/libc/tests/secure/Makefile b/lib/libc/tests/secure/Makefile
new file mode 100644
index 000000000000..d809f7cadd74
--- /dev/null
+++ b/lib/libc/tests/secure/Makefile
@@ -0,0 +1,20 @@
+.include <bsd.own.mk>
+
+TESTSDIR:=     ${TESTSBASE}/${RELDIR:C/libc\/tests/libc/}
+
+FORTIFY_TCATS+=        stdio
+FORTIFY_TCATS+=        string
+FORTIFY_TCATS+=        strings
+FORTIFY_TCATS+=        unistd
+
+# 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 <bsd.test.mk>
diff --git a/lib/libc/tests/secure/fortify_stdio_test.c 
b/lib/libc/tests/secure/fortify_stdio_test.c
new file mode 100644
index 000000000000..20ecdab89a8b
--- /dev/null
+++ b/lib/libc/tests/secure/fortify_stdio_test.c
@@ -0,0 +1,383 @@
+/* @generated by `generate-fortify-tests.lua "stdio"` */
+
+#define        _FORTIFY_SOURCE 2
+#define        TMPFILE_SIZE    (1024 * 32)
+
+#include <sys/param.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <atf-c.h>
+
+/*
+ * 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);
+}
+
+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_TP_ADD_TCS(tp)
+{
+       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);
+       return (atf_no_error());
+}
diff --git a/lib/libc/tests/secure/fortify_string_test.c 
b/lib/libc/tests/secure/fortify_string_test.c
new file mode 100644
index 000000000000..109ef40fd62d
--- /dev/null
+++ b/lib/libc/tests/secure/fortify_string_test.c
@@ -0,0 +1,1415 @@
+/* @generated by `generate-fortify-tests.lua "string"` */
+
+#define        _FORTIFY_SOURCE 2
+#define        TMPFILE_SIZE    (1024 * 32)
+
+#include <sys/param.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>
+#include <sysexits.h>
+#include <unistd.h>
+#include <atf-c.h>
+
+/*
+ * 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);
+}
+
+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(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
+
+}
+
*** 2503 LINES SKIPPED ***

Reply via email to