From: Roy Marples Date: Sat, 5 Sep 2020 15:16:22 +0000 (+0100) Subject: dhcpcd: Setup a socketpair in the launcher to write to stderr X-Git-Tag: v9.2.0~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb70c7ebdf80a3ee7d5146a877061503bf58c6d4;p=thirdparty%2Fdhcpcd.git dhcpcd: Setup a socketpair in the launcher to write to stderr Rather than duping stderr down to the processes. This allows us to reopen stdout and stderr onto /dev/null right away and means only the launcher process writes to stderr. The downside is that any stdout from the script is now lost. If that's needed, we could setup a stdout socketpair as well. --- diff --git a/src/dhcpcd.c b/src/dhcpcd.c index 2dc98d6c..86b994f8 100644 --- a/src/dhcpcd.c +++ b/src/dhcpcd.c @@ -1776,6 +1776,23 @@ dhcpcd_fork_cb(void *arg) eloop_exit(ctx->eloop, exit_code); } +static void +dhcpcd_stderr_cb(void *arg) +{ + struct dhcpcd_ctx *ctx = arg; + char log[BUFSIZ]; + ssize_t len; + + len = read(ctx->stderr_fd, log, sizeof(log)); + if (len == -1) { + logerr(__func__); + return; + } + + log[len] = '\0'; + fprintf(stderr, "%s", log); +} + int main(int argc, char **argv) { @@ -1789,7 +1806,7 @@ main(int argc, char **argv) ssize_t len; #if defined(USE_SIGNALS) || !defined(THERE_IS_NO_FORK) pid_t pid; - int sigpipe[2]; + int fork_fd[2], stderr_fd[2]; #endif #ifdef USE_SIGNALS int sig = 0; @@ -2223,12 +2240,16 @@ printpidfile: #endif #if defined(USE_SIGNALS) && !defined(THERE_IS_NO_FORK) - if (pipe(sigpipe) == -1) { - logerr("pipe"); + if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fork_fd) == -1 || + xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, stderr_fd) == -1) + { + logerr("socketpair"); goto exit_failure; } #ifdef HAVE_CAPSICUM - if (ps_rights_limit_fdpair(sigpipe) == -1) { + if (ps_rights_limit_fdpair(fork_fd) == -1 || + ps_rights_limit_fdpair(stderr_fd) == 1) + { logerr("ps_rights_limit_fdpair"); goto exit_failure; } @@ -2238,8 +2259,13 @@ printpidfile: logerr("fork"); goto exit_failure; case 0: - ctx.fork_fd = sigpipe[1]; - close(sigpipe[0]); + ctx.fork_fd = fork_fd[1]; + close(fork_fd[0]); + logseterrfd(stderr_fd[1]); + close(stderr_fd[0]); + if (freopen(_PATH_DEVNULL, "w", stdout) == NULL || + freopen(_PATH_DEVNULL, "w", stderr) == NULL) + logerr("freopen"); if (setsid() == -1) { logerr("%s: setsid", __func__); goto exit_failure; @@ -2259,10 +2285,13 @@ printpidfile: break; default: ctx.options |= DHCPCD_FORKED; /* A lie */ - ctx.fork_fd = sigpipe[0]; - close(sigpipe[1]); + ctx.fork_fd = fork_fd[0]; + close(fork_fd[1]); + ctx.stderr_fd = stderr_fd[0]; + close(stderr_fd[1]); setproctitle("[launcher]"); eloop_event_add(ctx.eloop, ctx.fork_fd, dhcpcd_fork_cb, &ctx); + eloop_event_add(ctx.eloop, ctx.stderr_fd, dhcpcd_stderr_cb, &ctx); goto run_loop; } @@ -2281,22 +2310,6 @@ printpidfile: if_disable_rtadv(); #endif - if (isatty(STDOUT_FILENO) && - freopen(_PATH_DEVNULL, "r", stdout) == NULL) - logerr("%s: freopen stdout", __func__); - if (isatty(STDERR_FILENO)) { - int fd = dup(STDERR_FILENO); - - if (fd == -1) - logerr("%s: dup", __func__); - else if (logseterrfd(fd) == -1) - logerr("%s: logseterrfd", __func__); - else if (freopen(_PATH_DEVNULL, "r", stderr) == NULL) { - logseterrfd(-1); - logerr("%s: freopen stderr", __func__); - } - } - #ifdef PRIVSEP if (IN_PRIVSEP(&ctx) && ps_start(&ctx) == -1) { logerr("ps_start"); diff --git a/src/dhcpcd.h b/src/dhcpcd.h index d9719c0a..95b7e073 100644 --- a/src/dhcpcd.h +++ b/src/dhcpcd.h @@ -118,6 +118,7 @@ struct dhcpcd_ctx { char pidfile[sizeof(PIDFILE) + IF_NAMESIZE + 1]; char vendor[256]; int fork_fd; /* FD for the fork init signal pipe */ + int stderr_fd; /* FD for logging to stderr */ const char *cffile; unsigned long long options; char *logfile;