summaryrefslogtreecommitdiffstats
path: root/src/privsep-root.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2020-10-30 03:43:51 +0000
committerRoy Marples <roy@marples.name>2020-10-30 03:43:51 +0000
commitc3069de559a30980fa5c72af7e483d912f010002 (patch)
tree5e6cdd28bc68f2cfeaa0199ac167254f2b4c42b1 /src/privsep-root.c
parent25e2eec83b600968f01f7fdb3ebfc3c82fc8c742 (diff)
downloaddhcpcd-c3069de559a30980fa5c72af7e483d912f010002.tar.xz
privsep: Send all log messages to the privileged actioneer
If dhcpcd starts and no syslogd implementation is running then various syscall filters could be triggered when dhcpcd wants to syslog and it's already in a chroot. Not all libc openlog implementations support LOG_NDELAY and openlog does not return an error code and can also mask errno back to 0. So we have no way of knowing if we have a syslog connection or not. This means we cannot cache the connection at startup because syslog itself will try and open if no connection. As such, all logging is now directed to the dhcpcd privileged actioneer process which will handle all the syslog and log file writing actions. The only downside of this approach (other than an extra fd per process) is that we no longer know which PID raised the message. While we could put the correct PID in the logfile as we control the API, we cannot put it into syslog as we cannot control that API. As all privsep errors should log which function they came from this will hopefully not be an issue as on the happy path only the master process will log stuff.
Diffstat (limited to 'src/privsep-root.c')
-rw-r--r--src/privsep-root.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/privsep-root.c b/src/privsep-root.c
index 770dd953..209f2624 100644
--- a/src/privsep-root.c
+++ b/src/privsep-root.c
@@ -780,18 +780,34 @@ ps_root_dispatch(void *arg)
logerr(__func__);
}
+static void
+ps_root_syslog(void *arg)
+{
+ struct dhcpcd_ctx *ctx = arg;
+
+ if (loghandlesyslogfd(ctx->ps_syslog_fd) == -1)
+ logerr(__func__);
+}
+
pid_t
ps_root_start(struct dhcpcd_ctx *ctx)
{
- int fd[2];
+ int logfd[2], datafd[2];
pid_t pid;
- if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fd) == -1)
+ if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, logfd) == -1)
return -1;
- if (ps_setbuf_fdpair(fd) == -1)
+#ifdef PRIVSEP_RIGHTS
+ if (ps_rights_limit_fdpair(logfd) == -1)
+ return -1;
+#endif
+
+ if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, datafd) == -1)
+ return -1;
+ if (ps_setbuf_fdpair(datafd) == -1)
return -1;
#ifdef PRIVSEP_RIGHTS
- if (ps_rights_limit_fdpair(fd) == -1)
+ if (ps_rights_limit_fdpair(datafd) == -1)
return -1;
#endif
@@ -800,14 +816,22 @@ ps_root_start(struct dhcpcd_ctx *ctx)
ps_root_startcb, ps_root_signalcb, 0);
if (pid == 0) {
- ctx->ps_data_fd = fd[1];
- close(fd[0]);
+ ctx->ps_syslog_fd = logfd[1];
+ if (eloop_event_add(ctx->eloop, ctx->ps_syslog_fd,
+ ps_root_syslog, ctx) == -1)
+ return -1;
+ close(logfd[0]);
+ ctx->ps_data_fd = datafd[1];
+ close(datafd[0]);
return 0;
} else if (pid == -1)
return -1;
- ctx->ps_data_fd = fd[0];
- close(fd[1]);
+ logsetsyslogfd(logfd[0]);
+ close(logfd[1]);
+
+ ctx->ps_data_fd = datafd[0];
+ close(datafd[1]);
if (eloop_event_add(ctx->eloop, ctx->ps_data_fd,
ps_root_dispatch, ctx) == -1)
return -1;