git: 22178cb29f03 - main - libc: tests: fix the gethostname() and getdomainname() tests

From: Kyle Evans <kevans_at_FreeBSD.org>
Date: Thu, 20 Mar 2025 04:44:35 UTC
The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=22178cb29f03a3b7bf919f3605e0cd5d6b18fa0a

commit 22178cb29f03a3b7bf919f3605e0cd5d6b18fa0a
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-03-20 04:43:23 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2025-03-20 04:44:26 +0000

    libc: tests: fix the gethostname() and getdomainname() tests
    
    Instead of relying on any particular domainname and hostname to succeed,
    spin up a jail before we execute the test with them set to some known,
    fixed values.  This allows them to be meaningfully tested -- previously,
    they were skipped much more often than not.
    
    Reported by:    jlduran
    Reviewed by:    jlduran, markj
    Differential Revision:  https://reviews.freebsd.org/D49237
---
 lib/libc/tests/secure/fortify_poll_test.c        |   1 +
 lib/libc/tests/secure/fortify_random_test.c      |   1 +
 lib/libc/tests/secure/fortify_select_test.c      |   1 +
 lib/libc/tests/secure/fortify_socket_test.c      |   1 +
 lib/libc/tests/secure/fortify_stdio_test.c       |   1 +
 lib/libc/tests/secure/fortify_stdlib_test.c      |   1 +
 lib/libc/tests/secure/fortify_string_test.c      |   1 +
 lib/libc/tests/secure/fortify_strings_test.c     |   1 +
 lib/libc/tests/secure/fortify_uio_test.c         |   1 +
 lib/libc/tests/secure/fortify_unistd_test.c      | 137 ++++++++++-------------
 lib/libc/tests/secure/fortify_wchar_test.c       |   1 +
 lib/libc/tests/secure/generate-fortify-tests.lua |  54 ++++++---
 12 files changed, 109 insertions(+), 92 deletions(-)

diff --git a/lib/libc/tests/secure/fortify_poll_test.c b/lib/libc/tests/secure/fortify_poll_test.c
index 9a5610cc3f0d..3810c16c122f 100644
--- a/lib/libc/tests/secure/fortify_poll_test.c
+++ b/lib/libc/tests/secure/fortify_poll_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
diff --git a/lib/libc/tests/secure/fortify_random_test.c b/lib/libc/tests/secure/fortify_random_test.c
index 41100fe5a5e2..2f47c981b5ae 100644
--- a/lib/libc/tests/secure/fortify_random_test.c
+++ b/lib/libc/tests/secure/fortify_random_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
diff --git a/lib/libc/tests/secure/fortify_select_test.c b/lib/libc/tests/secure/fortify_select_test.c
index aff13ccf58d2..5ee97a352e2e 100644
--- a/lib/libc/tests/secure/fortify_select_test.c
+++ b/lib/libc/tests/secure/fortify_select_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
diff --git a/lib/libc/tests/secure/fortify_socket_test.c b/lib/libc/tests/secure/fortify_socket_test.c
index 1f0b0f144f40..3d2dc86f4e1c 100644
--- a/lib/libc/tests/secure/fortify_socket_test.c
+++ b/lib/libc/tests/secure/fortify_socket_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
diff --git a/lib/libc/tests/secure/fortify_stdio_test.c b/lib/libc/tests/secure/fortify_stdio_test.c
index 82f45b827411..17842393a740 100644
--- a/lib/libc/tests/secure/fortify_stdio_test.c
+++ b/lib/libc/tests/secure/fortify_stdio_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
diff --git a/lib/libc/tests/secure/fortify_stdlib_test.c b/lib/libc/tests/secure/fortify_stdlib_test.c
index 01ed3e72172a..ae021e8418f7 100644
--- a/lib/libc/tests/secure/fortify_stdlib_test.c
+++ b/lib/libc/tests/secure/fortify_stdlib_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
diff --git a/lib/libc/tests/secure/fortify_string_test.c b/lib/libc/tests/secure/fortify_string_test.c
index 17dec871b32c..cfea261ff66f 100644
--- a/lib/libc/tests/secure/fortify_string_test.c
+++ b/lib/libc/tests/secure/fortify_string_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
diff --git a/lib/libc/tests/secure/fortify_strings_test.c b/lib/libc/tests/secure/fortify_strings_test.c
index 4ad5d58c5300..9f7d37a2480e 100644
--- a/lib/libc/tests/secure/fortify_strings_test.c
+++ b/lib/libc/tests/secure/fortify_strings_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
diff --git a/lib/libc/tests/secure/fortify_uio_test.c b/lib/libc/tests/secure/fortify_uio_test.c
index 5f12ffc08e1d..46b46ed2f7df 100644
--- a/lib/libc/tests/secure/fortify_uio_test.c
+++ b/lib/libc/tests/secure/fortify_uio_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
diff --git a/lib/libc/tests/secure/fortify_unistd_test.c b/lib/libc/tests/secure/fortify_unistd_test.c
index b3880dc4f369..b12ef2bbb8ea 100644
--- a/lib/libc/tests/secure/fortify_unistd_test.c
+++ b/lib/libc/tests/secure/fortify_unistd_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
@@ -162,6 +163,27 @@ replace_stdin(void)
 		close(fd);
 }
 
+#define	JAIL_HOSTNAME	"host.example.com"
+#define	JAIL_DOMAINNAME	"example.com"
+static void
+dhost_jail(void)
+{
+	struct iovec iov[4];
+	int jid;
+
+	iov[0].iov_base = __DECONST(char *, "host.hostname");
+	iov[0].iov_len = sizeof("host.hostname");
+	iov[1].iov_base = __DECONST(char *, JAIL_HOSTNAME);
+	iov[1].iov_len = sizeof(JAIL_HOSTNAME);
+	iov[2].iov_base = __DECONST(char *, "host.domainname");
+	iov[2].iov_len = sizeof("host.domainname");
+	iov[3].iov_base = __DECONST(char *, JAIL_DOMAINNAME);
+	iov[3].iov_len = sizeof(JAIL_DOMAINNAME);
+
+	jid = jail_set(iov, nitems(iov), JAIL_CREATE | JAIL_ATTACH);
+	ATF_REQUIRE_MSG(jid > 0, "Jail creation failed: %s", strerror(errno));
+}
+
 ATF_TC(getcwd_before_end);
 ATF_TC_HEAD(getcwd_before_end, tc)
 {
@@ -1354,24 +1376,21 @@ monitor:
 ATF_TC(getdomainname_before_end);
 ATF_TC_HEAD(getdomainname_before_end, tc)
 {
+	atf_tc_set_md_var(tc, "require.user", "root");
 }
 ATF_TC_BODY(getdomainname_before_end, tc)
 {
 #define BUF &__stack.__buf
 	struct {
 		uint8_t padding_l;
-		unsigned char __buf[4];
+		unsigned char __buf[12];
 		uint8_t padding_r;
 	} __stack;
 	const size_t __bufsz __unused = sizeof(__stack.__buf);
-	const size_t __len = 4 - 1;
+	const size_t __len = 12 - 1;
 	const size_t __idx __unused = __len - 1;
-	char sysdomain[256];
-
-	(void)getdomainname(sysdomain, __len);
-	if (strlen(sysdomain) <= __len)
-		atf_tc_skip("domain name too short for testing");
 
+	dhost_jail();
 	getdomainname(__stack.__buf, __len);
 #undef BUF
 
@@ -1380,24 +1399,21 @@ ATF_TC_BODY(getdomainname_before_end, tc)
 ATF_TC(getdomainname_end);
 ATF_TC_HEAD(getdomainname_end, tc)
 {
+	atf_tc_set_md_var(tc, "require.user", "root");
 }
 ATF_TC_BODY(getdomainname_end, tc)
 {
 #define BUF &__stack.__buf
 	struct {
 		uint8_t padding_l;
-		unsigned char __buf[4];
+		unsigned char __buf[12];
 		uint8_t padding_r;
 	} __stack;
 	const size_t __bufsz __unused = sizeof(__stack.__buf);
-	const size_t __len = 4;
+	const size_t __len = 12;
 	const size_t __idx __unused = __len - 1;
-	char sysdomain[256];
-
-	(void)getdomainname(sysdomain, __len);
-	if (strlen(sysdomain) <= __len)
-		atf_tc_skip("domain name too short for testing");
 
+	dhost_jail();
 	getdomainname(__stack.__buf, __len);
 #undef BUF
 
@@ -1406,6 +1422,7 @@ ATF_TC_BODY(getdomainname_end, tc)
 ATF_TC(getdomainname_heap_before_end);
 ATF_TC_HEAD(getdomainname_heap_before_end, tc)
 {
+	atf_tc_set_md_var(tc, "require.user", "root");
 }
 ATF_TC_BODY(getdomainname_heap_before_end, tc)
 {
@@ -1415,15 +1432,11 @@ ATF_TC_BODY(getdomainname_heap_before_end, tc)
 		unsigned char * __buf;
 		uint8_t padding_r;
 	} __stack;
-	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
-	const size_t __len = 4 - 1;
+	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (12);
+	const size_t __len = 12 - 1;
 	const size_t __idx __unused = __len - 1;
-	char sysdomain[256];
-
-	(void)getdomainname(sysdomain, __len);
-	if (strlen(sysdomain) <= __len)
-		atf_tc_skip("domain name too short for testing");
 
+	dhost_jail();
 	__stack.__buf = malloc(__bufsz);
 
 	getdomainname(__stack.__buf, __len);
@@ -1434,6 +1447,7 @@ ATF_TC_BODY(getdomainname_heap_before_end, tc)
 ATF_TC(getdomainname_heap_end);
 ATF_TC_HEAD(getdomainname_heap_end, tc)
 {
+	atf_tc_set_md_var(tc, "require.user", "root");
 }
 ATF_TC_BODY(getdomainname_heap_end, tc)
 {
@@ -1443,15 +1457,11 @@ ATF_TC_BODY(getdomainname_heap_end, tc)
 		unsigned char * __buf;
 		uint8_t padding_r;
 	} __stack;
-	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
-	const size_t __len = 4;
+	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (12);
+	const size_t __len = 12;
 	const size_t __idx __unused = __len - 1;
-	char sysdomain[256];
-
-	(void)getdomainname(sysdomain, __len);
-	if (strlen(sysdomain) <= __len)
-		atf_tc_skip("domain name too short for testing");
 
+	dhost_jail();
 	__stack.__buf = malloc(__bufsz);
 
 	getdomainname(__stack.__buf, __len);
@@ -1462,6 +1472,7 @@ ATF_TC_BODY(getdomainname_heap_end, tc)
 ATF_TC(getdomainname_heap_after_end);
 ATF_TC_HEAD(getdomainname_heap_after_end, tc)
 {
+	atf_tc_set_md_var(tc, "require.user", "root");
 }
 ATF_TC_BODY(getdomainname_heap_after_end, tc)
 {
@@ -1471,17 +1482,13 @@ ATF_TC_BODY(getdomainname_heap_after_end, tc)
 		unsigned char * __buf;
 		uint8_t padding_r;
 	} __stack;
-	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
-	const size_t __len = 4 + 1;
+	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (12);
+	const size_t __len = 12 + 1;
 	const size_t __idx __unused = __len - 1;
 	pid_t __child;
 	int __status;
-	char sysdomain[256];
-
-	(void)getdomainname(sysdomain, __len);
-	if (strlen(sysdomain) <= __len)
-		atf_tc_skip("domain name too short for testing");
 
+	dhost_jail();
 	__child = fork();
 	ATF_REQUIRE(__child >= 0);
 	if (__child > 0)
@@ -1663,25 +1670,21 @@ monitor:
 ATF_TC(gethostname_before_end);
 ATF_TC_HEAD(gethostname_before_end, tc)
 {
+	atf_tc_set_md_var(tc, "require.user", "root");
 }
 ATF_TC_BODY(gethostname_before_end, tc)
 {
 #define BUF &__stack.__buf
 	struct {
 		uint8_t padding_l;
-		unsigned char __buf[4];
+		unsigned char __buf[17];
 		uint8_t padding_r;
 	} __stack;
 	const size_t __bufsz __unused = sizeof(__stack.__buf);
-	const size_t __len = 4 - 1;
+	const size_t __len = 17 - 1;
 	const size_t __idx __unused = __len - 1;
-	char syshost[256];
-	int error;
-
-	error = gethostname(syshost, __len);
-	if (error != 0 || strlen(syshost) <= __len)
-		atf_tc_skip("hostname too short for testing");
 
+	dhost_jail();
 	gethostname(__stack.__buf, __len);
 #undef BUF
 
@@ -1690,25 +1693,21 @@ ATF_TC_BODY(gethostname_before_end, tc)
 ATF_TC(gethostname_end);
 ATF_TC_HEAD(gethostname_end, tc)
 {
+	atf_tc_set_md_var(tc, "require.user", "root");
 }
 ATF_TC_BODY(gethostname_end, tc)
 {
 #define BUF &__stack.__buf
 	struct {
 		uint8_t padding_l;
-		unsigned char __buf[4];
+		unsigned char __buf[17];
 		uint8_t padding_r;
 	} __stack;
 	const size_t __bufsz __unused = sizeof(__stack.__buf);
-	const size_t __len = 4;
+	const size_t __len = 17;
 	const size_t __idx __unused = __len - 1;
-	char syshost[256];
-	int error;
-
-	error = gethostname(syshost, __len);
-	if (error != 0 || strlen(syshost) <= __len)
-		atf_tc_skip("hostname too short for testing");
 
+	dhost_jail();
 	gethostname(__stack.__buf, __len);
 #undef BUF
 
@@ -1717,6 +1716,7 @@ ATF_TC_BODY(gethostname_end, tc)
 ATF_TC(gethostname_heap_before_end);
 ATF_TC_HEAD(gethostname_heap_before_end, tc)
 {
+	atf_tc_set_md_var(tc, "require.user", "root");
 }
 ATF_TC_BODY(gethostname_heap_before_end, tc)
 {
@@ -1726,16 +1726,11 @@ ATF_TC_BODY(gethostname_heap_before_end, tc)
 		unsigned char * __buf;
 		uint8_t padding_r;
 	} __stack;
-	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
-	const size_t __len = 4 - 1;
+	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (17);
+	const size_t __len = 17 - 1;
 	const size_t __idx __unused = __len - 1;
-	char syshost[256];
-	int error;
-
-	error = gethostname(syshost, __len);
-	if (error != 0 || strlen(syshost) <= __len)
-		atf_tc_skip("hostname too short for testing");
 
+	dhost_jail();
 	__stack.__buf = malloc(__bufsz);
 
 	gethostname(__stack.__buf, __len);
@@ -1746,6 +1741,7 @@ ATF_TC_BODY(gethostname_heap_before_end, tc)
 ATF_TC(gethostname_heap_end);
 ATF_TC_HEAD(gethostname_heap_end, tc)
 {
+	atf_tc_set_md_var(tc, "require.user", "root");
 }
 ATF_TC_BODY(gethostname_heap_end, tc)
 {
@@ -1755,16 +1751,11 @@ ATF_TC_BODY(gethostname_heap_end, tc)
 		unsigned char * __buf;
 		uint8_t padding_r;
 	} __stack;
-	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
-	const size_t __len = 4;
+	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (17);
+	const size_t __len = 17;
 	const size_t __idx __unused = __len - 1;
-	char syshost[256];
-	int error;
-
-	error = gethostname(syshost, __len);
-	if (error != 0 || strlen(syshost) <= __len)
-		atf_tc_skip("hostname too short for testing");
 
+	dhost_jail();
 	__stack.__buf = malloc(__bufsz);
 
 	gethostname(__stack.__buf, __len);
@@ -1775,6 +1766,7 @@ ATF_TC_BODY(gethostname_heap_end, tc)
 ATF_TC(gethostname_heap_after_end);
 ATF_TC_HEAD(gethostname_heap_after_end, tc)
 {
+	atf_tc_set_md_var(tc, "require.user", "root");
 }
 ATF_TC_BODY(gethostname_heap_after_end, tc)
 {
@@ -1784,18 +1776,13 @@ ATF_TC_BODY(gethostname_heap_after_end, tc)
 		unsigned char * __buf;
 		uint8_t padding_r;
 	} __stack;
-	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
-	const size_t __len = 4 + 1;
+	const size_t __bufsz __unused = sizeof(*__stack.__buf) * (17);
+	const size_t __len = 17 + 1;
 	const size_t __idx __unused = __len - 1;
 	pid_t __child;
 	int __status;
-	char syshost[256];
-	int error;
-
-	error = gethostname(syshost, __len);
-	if (error != 0 || strlen(syshost) <= __len)
-		atf_tc_skip("hostname too short for testing");
 
+	dhost_jail();
 	__child = fork();
 	ATF_REQUIRE(__child >= 0);
 	if (__child > 0)
diff --git a/lib/libc/tests/secure/fortify_wchar_test.c b/lib/libc/tests/secure/fortify_wchar_test.c
index 9ac5d93ac078..43c7997bc6a3 100644
--- a/lib/libc/tests/secure/fortify_wchar_test.c
+++ b/lib/libc/tests/secure/fortify_wchar_test.c
@@ -4,6 +4,7 @@
 #define	TMPFILE_SIZE	(1024 * 32)
 
 #include <sys/param.h>
+#include <sys/jail.h>
 #include <sys/random.h>
 #include <sys/resource.h>
 #include <sys/select.h>
diff --git a/lib/libc/tests/secure/generate-fortify-tests.lua b/lib/libc/tests/secure/generate-fortify-tests.lua
index 3cb3278f017c..36ff01af7a17 100755
--- a/lib/libc/tests/secure/generate-fortify-tests.lua
+++ b/lib/libc/tests/secure/generate-fortify-tests.lua
@@ -62,6 +62,7 @@
 
 local includes = {
 	"sys/param.h",
+	"sys/jail.h",
 	"sys/random.h",
 	"sys/resource.h",
 	"sys/select.h",
@@ -87,6 +88,10 @@ local includes = {
 
 local tests_added = {}
 
+-- Configuration for tests that want the host/domainname
+local hostname = "host.example.com"
+local domainname = "example.com"
+
 -- Some of these will need to be excluded because clang sees the wrong size when
 -- an array is embedded inside a struct, we'll get something that looks more
 -- like __builtin_object_size(ptr, 0) than it does the correct
@@ -858,18 +863,14 @@ local all_tests = {
 		},
 		{
 			func = "getdomainname",
-			bufsize = "4",
+			bufsize = #domainname + 1,
 			arguments = {
 				"__buf",
 				"__len",
 			},
+			need_root = true,
 			exclude = excludes_stack_overflow,
-			stackvars = "\tchar sysdomain[256];\n",
-			early_init = [[
-	(void)getdomainname(sysdomain, __len);
-	if (strlen(sysdomain) <= __len)
-		atf_tc_skip("domain name too short for testing");
-]]
+			early_init = "	dhost_jail();",
 		},
 		{
 			func = "getentropy",
@@ -881,21 +882,14 @@ local all_tests = {
 		},
 		{
 			func = "gethostname",
-			bufsize = "4",
+			bufsize = #hostname + 1,
 			arguments = {
 				"__buf",
 				"__len",
 			},
+			need_root = true,
 			exclude = excludes_stack_overflow,
-			stackvars = [[
-	char syshost[256];
-	int error;
-]],
-			early_init = [[
-	error = gethostname(syshost, __len);
-	if (error != 0 || strlen(syshost) <= __len)
-		atf_tc_skip("hostname too short for testing");
-]]
+			early_init = "	dhost_jail();",
 		},
 		{
 			func = "getlogin_r",
@@ -1515,6 +1509,32 @@ replace_stdin(void)
 
 ]])
 
+if tcat == "unistd" then
+	fh:write("#define	JAIL_HOSTNAME	\"" .. hostname .. "\"\n")
+	fh:write("#define	JAIL_DOMAINNAME	\"" .. domainname .. "\"\n")
+	fh:write([[
+static void
+dhost_jail(void)
+{
+	struct iovec iov[4];
+	int jid;
+
+	iov[0].iov_base = __DECONST(char *, "host.hostname");
+	iov[0].iov_len = sizeof("host.hostname");
+	iov[1].iov_base = __DECONST(char *, JAIL_HOSTNAME);
+	iov[1].iov_len = sizeof(JAIL_HOSTNAME);
+	iov[2].iov_base = __DECONST(char *, "host.domainname");
+	iov[2].iov_len = sizeof("host.domainname");
+	iov[3].iov_base = __DECONST(char *, JAIL_DOMAINNAME);
+	iov[3].iov_len = sizeof(JAIL_DOMAINNAME);
+
+	jid = jail_set(iov, nitems(iov), JAIL_CREATE | JAIL_ATTACH);
+	ATF_REQUIRE_MSG(jid > 0, "Jail creation failed: %s", strerror(errno));
+}
+
+]])
+end
+
 for _, def in pairs(tests) do
 	local func = def.func
 	local function write_tests(heap)