Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 31 Jul 2026 14:22:30 +0000
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 1719b754a9ec - main - tests/libc: Fix fortify_source uio tests
Message-ID:  <6a6cafa6.1f4fe.491ec150@gitrepo.freebsd.org>

index | next in thread | raw e-mail

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,
 		},
 	},


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a6cafa6.1f4fe.491ec150>