Mercurial > hg > dhcpcd
diff src/logerr.c @ 5526:b1a3d9055662 draft
privsep: Allow logfile reopening in a chroot
Now that only the privileged actioneer does the actual logging
we can safely reopen the file we are logging to.
This also closes and re-opens the syslog connection.
| author | Roy Marples <roy@marples.name> |
|---|---|
| date | Fri, 30 Oct 2020 14:19:16 +0000 |
| parents | 26b5d9bc2985 |
| children | 071a9ea18363 |
line wrap: on
line diff
--- a/src/logerr.c Fri Oct 30 03:43:51 2020 +0000 +++ b/src/logerr.c Fri Oct 30 14:19:16 2020 +0000 @@ -48,14 +48,15 @@ #endif /* syslog protocol is 1k message max, RFC 3164 section 4.1 */ -#define LOGERR_SYSLOGBUF 1024 + sizeof(int) +#define LOGERR_SYSLOGBUF 1024 + sizeof(int) + sizeof(pid_t) #define UNUSED(a) (void)(a) struct logctx { char log_buf[BUFSIZ]; unsigned int log_opts; - int log_syslogfd; + int log_fd; + pid_t log_pid; #ifndef SMALL FILE *log_file; #ifdef LOGERR_TAG @@ -67,7 +68,8 @@ static struct logctx _logctx = { /* syslog style, but without the hostname or tag. */ .log_opts = LOGERR_LOG | LOGERR_LOG_DATE | LOGERR_LOG_PID, - .log_syslogfd = -1, + .log_fd = -1, + .log_pid = 0, }; #if defined(__linux__) @@ -155,7 +157,13 @@ log_pid = ((stream == stderr && ctx->log_opts & LOGERR_ERR_PID) || (stream != stderr && ctx->log_opts & LOGERR_LOG_PID)); if (log_pid) { - if ((e = fprintf(stream, "[%d]", getpid())) == -1) + pid_t pid; + + if (ctx->log_pid == 0) + pid = getpid(); + else + pid = ctx->log_pid; + if ((e = fprintf(stream, "[%d]", pid)) == -1) return -1; len += e; } @@ -206,15 +214,19 @@ struct logctx *ctx = &_logctx; int len = 0; - if (ctx->log_syslogfd != -1) { + if (ctx->log_fd != -1) { char buf[LOGERR_SYSLOGBUF]; + pid_t pid; memcpy(buf, &pri, sizeof(pri)); - len = vsnprintf(buf + sizeof(pri), sizeof(buf) - sizeof(pri), + pid = getpid(); + memcpy(buf + sizeof(pri), &pid, sizeof(pid)); + len = vsnprintf(buf + sizeof(pri) + sizeof(pid), + sizeof(buf) - sizeof(pri) - sizeof(pid), fmt, args); if (len != -1) - len = (int)write(ctx->log_syslogfd, buf, - ((size_t)++len) + sizeof(pri)); + len = (int)write(ctx->log_fd, buf, + ((size_t)++len) + sizeof(pri) + sizeof(pid)); return len; } @@ -351,24 +363,31 @@ } int -loggetsyslogfd(void) +loggetfd(void) { struct logctx *ctx = &_logctx; - return ctx->log_syslogfd; + return ctx->log_fd; } void -logsetsyslogfd(int fd) +logsetfd(int fd) { struct logctx *ctx = &_logctx; - ctx->log_syslogfd = fd; + ctx->log_fd = fd; +#ifndef SMALL + if (fd != -1 && ctx->log_file != NULL) { + fclose(ctx->log_file); + ctx->log_file = NULL; + } +#endif } int -loghandlesyslogfd(int fd) +logreadfd(int fd) { + struct logctx *ctx = &_logctx; char buf[LOGERR_SYSLOGBUF]; int len, pri; @@ -376,14 +395,18 @@ if (len == -1) return -1; - /* Ensure we have pri and a terminator */ - if (len < (int)sizeof(pri) + 1 || buf[len - 1] != '\0') { + /* Ensure we have pri, pid and a terminator */ + if (len < (int)(sizeof(pri) + sizeof(pid_t) + 1) || + buf[len - 1] != '\0') + { errno = EINVAL; return -1; } memcpy(&pri, buf, sizeof(pri)); - logmessage(pri, "%s", buf + sizeof(pri)); + memcpy(&ctx->log_pid, buf + sizeof(pri), sizeof(ctx->log_pid)); + logmessage(pri, "%s", buf + sizeof(pri) + sizeof(ctx->log_pid)); + ctx->log_pid = 0; return len; }
