git: f2c99600cbdf - stable/15 - tests/libc: Fix fortify_source uio tests
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 17 Aug 2026 12:10:22 UTC
The branch stable/15 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=f2c99600cbdfa9df93fd0566f49bb001495c91c8
commit f2c99600cbdfa9df93fd0566f49bb001495c91c8
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-07-31 14:20:00 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-08-17 12:07:41 +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
(cherry picked from commit 1719b754a9ec88fcf0f5f4b001b1b5d5d6db5819)
---
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,
},
},