[hackers] [st][PATCH] fix async-unsafe error paths in sigchld()

From: Avro <avro_AT_disroot.org>
Date: Mon, 29 Jun 2026 14:26:34 +0000

die() calls vfprintf(3) and exit(3), which are not
async-signal-safe. If SIGCHLD is handled while exiting, this
can make st hang or crash.

Commit d6ea0a1 replaced exit(3) by _exit(2) in sigchld()
but the error paths still call die(). Fix that by using
_exit(2) there as well.
---
 st.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/st.c b/st.c
index 6f40e35..c15ca4b 100644
--- a/st.c
+++ b/st.c
_AT_@ -712,19 +712,24 @@ execsh(char *cmd, char **args)
 void
 sigchld(int a)
 {
-	int stat;
+	int stat, olderrno;
 	pid_t p;
 
-	if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
-		die("waiting for pid %hd failed: %s\n", pid, strerror(errno));
+	olderrno = errno;
+	do {
+		p = waitpid(pid, &stat, WNOHANG);
+	} while (p < 0 && errno == EINTR);
 
-	if (pid != p)
+	if (p < 0)
+		_exit(1);
+
+	if (pid != p) {
+		errno = olderrno;
 		return;
+	}
 
-	if (WIFEXITED(stat) && WEXITSTATUS(stat))
-		die("child exited with status %d\n", WEXITSTATUS(stat));
-	else if (WIFSIGNALED(stat))
-		die("child terminated due to signal %d\n", WTERMSIG(stat));
+	if ((WIFEXITED(stat) && WEXITSTATUS(stat)) || WIFSIGNALED(stat))
+		_exit(1);
 	_exit(0);
 }
 
-- 
2.54.0
Received on Mon Jun 29 2026 - 16:26:34 CEST

This archive was generated by hypermail 2.3.0 : Mon Jun 29 2026 - 16:36:37 CEST