git: 7428ebfe7e25 - main - syslogd: Pre-open null file descriptor

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 28 Sep 2023 15:52:46 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=7428ebfe7e25d56e2a5853d36d2c34c54a2f4db3

commit 7428ebfe7e25d56e2a5853d36d2c34c54a2f4db3
Author:     Jake Freeland <jfree@FreeBSD.org>
AuthorDate: 2023-09-01 02:51:17 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2023-09-28 15:51:54 +0000

    syslogd: Pre-open null file descriptor
    
    Open _PATH_DEVNULL before entering capability mode. Access to /dev/null
    is needed for dup2() when piping commands.
    
    Reviewed by:    markj
    MFC after:      3 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D41381
---
 usr.sbin/syslogd/syslogd.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
index 9f4c21cab026..2ff39d8c3676 100644
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -398,6 +398,7 @@ static const int sigcatch[] = {
 	SIGCHLD,
 };
 
+static int	nulldesc;	/* /dev/null descriptor */
 static bool	Debug;		/* debug flag */
 static bool	Foreground = false; /* Run in foreground, instead of daemonizing */
 static bool	resolve = true;	/* resolve hostname */
@@ -803,6 +804,14 @@ main(int argc, char *argv[])
 	consfile.f_file = -1;
 	(void)strlcpy(consfile.fu_fname, _PATH_CONSOLE + sizeof(_PATH_DEV) - 1,
 	    sizeof(consfile.fu_fname));
+
+	nulldesc = open(_PATH_DEVNULL, O_RDWR);
+	if (nulldesc == -1) {
+		warn("cannot open %s", _PATH_DEVNULL);
+		pidfile_remove(pfh);
+		exit(1);
+	}
+
 	(void)strlcpy(bootfile, getbootfile(), sizeof(bootfile));
 
 	if ((!Foreground) && (!Debug)) {
@@ -3235,7 +3244,6 @@ markit(void)
 static int
 waitdaemon(int maxwait)
 {
-	int fd;
 	int status;
 	pid_t pid, childpid;
 
@@ -3266,13 +3274,9 @@ waitdaemon(int maxwait)
 		return (-1);
 
 	(void)chdir("/");
-	if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
-		(void)dup2(fd, STDIN_FILENO);
-		(void)dup2(fd, STDOUT_FILENO);
-		(void)dup2(fd, STDERR_FILENO);
-		if (fd > STDERR_FILENO)
-			(void)close(fd);
-	}
+	(void)dup2(nulldesc, STDIN_FILENO);
+	(void)dup2(nulldesc, STDOUT_FILENO);
+	(void)dup2(nulldesc, STDERR_FILENO);
 	return (getppid());
 }
 
@@ -3595,20 +3599,16 @@ static int
 p_open(const char *prog, int *rpd)
 {
 	sigset_t sigset = { };
-	int nulldesc, pfd[2], pd;
+	int pfd[2], pd;
 	pid_t pid;
 	char *argv[4]; /* sh -c cmd NULL */
 	char errmsg[200];
 
 	if (pipe(pfd) == -1)
 		return (-1);
-	if ((nulldesc = open(_PATH_DEVNULL, O_RDWR)) == -1)
-		/* we are royally screwed anyway */
-		return (-1);
 
 	switch ((pid = pdfork(&pd, PD_CLOEXEC))) {
 	case -1:
-		close(nulldesc);
 		return (-1);
 
 	case 0:
@@ -3639,7 +3639,6 @@ p_open(const char *prog, int *rpd)
 		(void)execvp(_PATH_BSHELL, argv);
 		_exit(255);
 	}
-	close(nulldesc);
 	close(pfd[0]);
 	/*
 	 * Avoid blocking on a hung pipe.  With O_NONBLOCK, we are