git: 080a4087014e - main - tests: Fix race condition in aslr_setuid

From: Dag-Erling Smørgrav <des_at_FreeBSD.org>
Date: Mon, 22 Jun 2026 13:26:16 UTC
The branch main has been updated by des:

URL: https://cgit.FreeBSD.org/src/commit/?id=080a4087014e1d19136cc77028019d98b5c69e1e

commit 080a4087014e1d19136cc77028019d98b5c69e1e
Author:     Dag-Erling Smørgrav <des@FreeBSD.org>
AuthorDate: 2026-06-22 13:23:31 +0000
Commit:     Dag-Erling Smørgrav <des@FreeBSD.org>
CommitDate: 2026-06-22 13:23:48 +0000

    tests: Fix race condition in aslr_setuid
    
    Use a cloexec pipe to block the parent until the child is ready.
    
    While here, redirect the output from ping to /dev/null, and mark the
    test as requiring the inet feature since we ping the IPv4 loopback.
    
    PR:             296116
    MFC after:      1 week
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D57734
---
 tests/sys/kern/Makefile |  1 +
 tests/sys/kern/aslr.c   | 16 +++++++++++++---
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/tests/sys/kern/Makefile b/tests/sys/kern/Makefile
index 3b09ee3181d2..728917b062c5 100644
--- a/tests/sys/kern/Makefile
+++ b/tests/sys/kern/Makefile
@@ -92,6 +92,7 @@ PROGS+=		coredump_phnum_helper
 PROGS+=		pdeathsig_helper
 PROGS+=		sendfile_helper
 
+CFLAGS.aslr+=				-I${SRCTOP}/tests
 LIBADD.aslr+=				util
 LIBADD.copy_file_range+=		md
 LIBADD.jail_lookup_root+=		jail util
diff --git a/tests/sys/kern/aslr.c b/tests/sys/kern/aslr.c
index 13038054603c..7d5282fc7cf3 100644
--- a/tests/sys/kern/aslr.c
+++ b/tests/sys/kern/aslr.c
@@ -11,6 +11,7 @@
 #include <sys/user.h>
 #include <sys/wait.h>
 
+#include <fcntl.h>
 #include <libutil.h>
 #include <pwd.h>
 #include <signal.h>
@@ -19,6 +20,7 @@
 #include <unistd.h>
 
 #include <atf-c.h>
+#include "freebsd_test_suite/macros.h"
 
 /*
  * Spawn an unprivileged child with ASLR force-disabled, which then execs
@@ -30,16 +32,21 @@ spawn_ping(const atf_tc_t *tc)
 	const char *user;
 	struct passwd *passwd;
 	pid_t child;
-	int arg, error;
+	int arg, error, ctl[2];
+	char dummy;
 
 	user = atf_tc_get_config_var(tc, "unprivileged_user");
 	passwd = getpwnam(user);
 	ATF_REQUIRE(passwd != NULL);
 
+	ATF_REQUIRE(pipe2(ctl, O_CLOEXEC) == 0);
 	child = fork();
 	ATF_REQUIRE(child >= 0);
 	if (child == 0) {
-		if (seteuid(passwd->pw_uid) != 0)
+		if (close(ctl[0]) != 0 ||
+		    close(STDOUT_FILENO) != 0 ||
+		    open("/dev/null", O_WRONLY | O_APPEND) != STDOUT_FILENO ||
+		    seteuid(passwd->pw_uid) != 0)
 			_exit(1);
 
 		arg = PROC_ASLR_FORCE_DISABLE;
@@ -50,7 +57,9 @@ spawn_ping(const atf_tc_t *tc)
 		execl("/sbin/ping", "ping", "127.0.0.1", NULL);
 		_exit(127);
 	}
-	usleep(500000); /* XXX-MJ */
+	ATF_REQUIRE(close(ctl[1]) == 0);
+	ATF_REQUIRE(read(ctl[0], &dummy, 1) == 0);
+	ATF_REQUIRE(close(ctl[0]) == 0);
 
 	return (child);
 }
@@ -98,6 +107,7 @@ ATF_TC_BODY(aslr_setuid, tc)
 	pid_t child, pid;
 	int arg, error, st;
 
+	ATF_REQUIRE_FEATURE("inet");
 	if (!atf_tc_has_config_var(tc, "unprivileged_user"))
 		atf_tc_skip("unprivileged_user not set");