git: 1719b754a9ec - main - tests/libc: Fix fortify_source uio tests
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 31 Jul 2026 14:22:30 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=1719b754a9ec88fcf0f5f4b001b1b5d5d6db5819
commit 1719b754a9ec88fcf0f5f4b001b1b5d5d6db5819
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-07-31 14:20:00 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-07-31 14:20:00 +0000
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
---
lib/libc/tests/secure/fortify_uio_test.c | 100 ++++++++++++++++++-----
lib/libc/tests/secure/generate-fortify-tests.lua | 27 ++++--
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,
},
},