aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2026-07-31 14:20:00 +0000
committerMark Johnston <markj@FreeBSD.org>2026-07-31 14:20:00 +0000
commit1719b754a9ec88fcf0f5f4b001b1b5d5d6db5819 (patch)
tree5b1410904eee9e77e6ffd829b1f6807f008b54ae
parentb9d07a4308226b683b64827e0aaed1180e0da996 (diff)
tests/libc: Fix fortify_source uio tests
Some of the preadv() and readv() tests were not initializing the iovecs they pass to the system call. When the system call is expected to fail, that's fine since the FORTIFY_SOURCE checks cause the process to be aborted. However, in the rest of the test cases, the (p)readv() call could cause spurious test failures, e.g., when an uninitialized iov entry points to the current stack frame and the canary gets overwritten. Modify the tests to explicitly initialize iov entries to avoid this. The "iov" variants don't have this problem, so leave them alone. Reviewed by: kevans MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D58289
-rw-r--r--lib/libc/tests/secure/fortify_uio_test.c100
-rwxr-xr-xlib/libc/tests/secure/generate-fortify-tests.lua27
2 files changed, 98 insertions, 29 deletions
diff --git a/lib/libc/tests/secure/fortify_uio_test.c b/lib/libc/tests/secure/fortify_uio_test.c
index b1b51eff824c..45f63f3d0975 100644
--- a/lib/libc/tests/secure/fortify_uio_test.c
+++ b/lib/libc/tests/secure/fortify_uio_test.c
@@ -181,6 +181,11 @@ ATF_TC_BODY(readv_before_end, tc)
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
readv(STDIN_FILENO, __stack.__buf, __len);
#undef BUF
@@ -204,6 +209,11 @@ ATF_TC_BODY(readv_end, tc)
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
readv(STDIN_FILENO, __stack.__buf, __len);
#undef BUF
@@ -236,6 +246,11 @@ ATF_TC_BODY(readv_after_end, tc)
disable_coredumps();
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
readv(STDIN_FILENO, __stack.__buf, __len);
_exit(EX_SOFTWARE); /* Should have aborted. */
@@ -282,6 +297,11 @@ ATF_TC_BODY(readv_heap_before_end, tc)
__stack.__buf = malloc(__bufsz);
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
readv(STDIN_FILENO, __stack.__buf, __len);
#undef BUF
@@ -306,6 +326,11 @@ ATF_TC_BODY(readv_heap_end, tc)
__stack.__buf = malloc(__bufsz);
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
readv(STDIN_FILENO, __stack.__buf, __len);
#undef BUF
@@ -339,6 +364,11 @@ ATF_TC_BODY(readv_heap_after_end, tc)
__stack.__buf = malloc(__bufsz);
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
readv(STDIN_FILENO, __stack.__buf, __len);
_exit(EX_SOFTWARE); /* Should have aborted. */
@@ -383,11 +413,11 @@ ATF_TC_BODY(readv_iov_before_end, tc)
const size_t __idx __unused = __len - 1;
struct iovec iov[1];
+ replace_stdin();
+
iov[0].iov_base = __stack.__buf;
iov[0].iov_len = __len;
- replace_stdin();
-
readv(STDIN_FILENO, iov, nitems(iov));
#undef BUF
@@ -410,11 +440,11 @@ ATF_TC_BODY(readv_iov_end, tc)
const size_t __idx __unused = __len - 1;
struct iovec iov[1];
+ replace_stdin();
+
iov[0].iov_base = __stack.__buf;
iov[0].iov_len = __len;
- replace_stdin();
-
readv(STDIN_FILENO, iov, nitems(iov));
#undef BUF
@@ -438,11 +468,11 @@ ATF_TC_BODY(readv_iov_heap_before_end, tc)
struct iovec iov[1];
__stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
iov[0].iov_base = __stack.__buf;
iov[0].iov_len = __len;
- replace_stdin();
-
readv(STDIN_FILENO, iov, nitems(iov));
#undef BUF
@@ -466,11 +496,11 @@ ATF_TC_BODY(readv_iov_heap_end, tc)
struct iovec iov[1];
__stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
iov[0].iov_base = __stack.__buf;
iov[0].iov_len = __len;
- replace_stdin();
-
readv(STDIN_FILENO, iov, nitems(iov));
#undef BUF
@@ -503,11 +533,11 @@ ATF_TC_BODY(readv_iov_heap_after_end, tc)
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
iov[0].iov_base = __stack.__buf;
iov[0].iov_len = __len;
- replace_stdin();
-
readv(STDIN_FILENO, iov, nitems(iov));
_exit(EX_SOFTWARE); /* Should have aborted. */
@@ -553,6 +583,11 @@ ATF_TC_BODY(preadv_before_end, tc)
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
preadv(STDIN_FILENO, __stack.__buf, __len, 0);
#undef BUF
@@ -576,6 +611,11 @@ ATF_TC_BODY(preadv_end, tc)
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
preadv(STDIN_FILENO, __stack.__buf, __len, 0);
#undef BUF
@@ -608,6 +648,11 @@ ATF_TC_BODY(preadv_after_end, tc)
disable_coredumps();
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
preadv(STDIN_FILENO, __stack.__buf, __len, 0);
_exit(EX_SOFTWARE); /* Should have aborted. */
@@ -654,6 +699,11 @@ ATF_TC_BODY(preadv_heap_before_end, tc)
__stack.__buf = malloc(__bufsz);
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
preadv(STDIN_FILENO, __stack.__buf, __len, 0);
#undef BUF
@@ -678,6 +728,11 @@ ATF_TC_BODY(preadv_heap_end, tc)
__stack.__buf = malloc(__bufsz);
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
preadv(STDIN_FILENO, __stack.__buf, __len, 0);
#undef BUF
@@ -711,6 +766,11 @@ ATF_TC_BODY(preadv_heap_after_end, tc)
__stack.__buf = malloc(__bufsz);
replace_stdin();
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+
preadv(STDIN_FILENO, __stack.__buf, __len, 0);
_exit(EX_SOFTWARE); /* Should have aborted. */
@@ -755,11 +815,11 @@ ATF_TC_BODY(preadv_iov_before_end, tc)
const size_t __idx __unused = __len - 1;
struct iovec iov[1];
+ replace_stdin();
+
iov[0].iov_base = __stack.__buf;
iov[0].iov_len = __len;
- replace_stdin();
-
preadv(STDIN_FILENO, iov, nitems(iov), 0);
#undef BUF
@@ -782,11 +842,11 @@ ATF_TC_BODY(preadv_iov_end, tc)
const size_t __idx __unused = __len - 1;
struct iovec iov[1];
+ replace_stdin();
+
iov[0].iov_base = __stack.__buf;
iov[0].iov_len = __len;
- replace_stdin();
-
preadv(STDIN_FILENO, iov, nitems(iov), 0);
#undef BUF
@@ -810,11 +870,11 @@ ATF_TC_BODY(preadv_iov_heap_before_end, tc)
struct iovec iov[1];
__stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
iov[0].iov_base = __stack.__buf;
iov[0].iov_len = __len;
- replace_stdin();
-
preadv(STDIN_FILENO, iov, nitems(iov), 0);
#undef BUF
@@ -838,11 +898,11 @@ ATF_TC_BODY(preadv_iov_heap_end, tc)
struct iovec iov[1];
__stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
iov[0].iov_base = __stack.__buf;
iov[0].iov_len = __len;
- replace_stdin();
-
preadv(STDIN_FILENO, iov, nitems(iov), 0);
#undef BUF
@@ -875,11 +935,11 @@ ATF_TC_BODY(preadv_iov_heap_after_end, tc)
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
iov[0].iov_base = __stack.__buf;
iov[0].iov_len = __len;
- replace_stdin();
-
preadv(STDIN_FILENO, iov, nitems(iov), 0);
_exit(EX_SOFTWARE); /* Should have aborted. */
diff --git a/lib/libc/tests/secure/generate-fortify-tests.lua b/lib/libc/tests/secure/generate-fortify-tests.lua
index ef34fb8513c8..c1c455e84b56 100755
--- a/lib/libc/tests/secure/generate-fortify-tests.lua
+++ b/lib/libc/tests/secure/generate-fortify-tests.lua
@@ -113,12 +113,21 @@ local printf_init = [[
srcvar[sizeof(srcvar) - 1] = '\0';
]]
-local readv_stackvars = "\tstruct iovec iov[1];\n"
local readv_init = [[
- iov[0].iov_base = __stack.__buf;
- iov[0].iov_len = __len;
+ replace_stdin();
+
+ for (size_t __i = 0; __i < 2; __i++) {
+ __stack.__buf[__i].iov_base = &__stack.padding_l;
+ __stack.__buf[__i].iov_len = 1;
+ }
+]]
+local readv_iov_stackvars = "\tstruct iovec iov[1];\n"
+local readv_iov_init = [[
replace_stdin();
+
+ iov[0].iov_base = __stack.__buf;
+ iov[0].iov_len = __len;
]]
local socket_stackvars = "\tint sock[2] = { -1, -1 };\n"
@@ -411,7 +420,7 @@ local all_tests = {
"__buf",
"__len",
},
- init = stdio_init,
+ init = readv_init,
},
{
func = "readv",
@@ -422,8 +431,8 @@ local all_tests = {
"nitems(iov)",
},
exclude = excludes_stack_overflow,
- stackvars = readv_stackvars,
- init = readv_init,
+ stackvars = readv_iov_stackvars,
+ init = readv_iov_init,
uses_len = true,
},
{
@@ -436,7 +445,7 @@ local all_tests = {
"__len",
"0",
},
- init = stdio_init,
+ init = readv_init,
},
{
func = "preadv",
@@ -448,8 +457,8 @@ local all_tests = {
"0",
},
exclude = excludes_stack_overflow,
- stackvars = readv_stackvars,
- init = readv_init,
+ stackvars = readv_iov_stackvars,
+ init = readv_iov_init,
uses_len = true,
},
},