comparison src/privsep-root.c @ 5525:26b5d9bc2985 draft

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.
author Roy Marples <roy@marples.name>
date Fri, 30 Oct 2020 03:43:51 +0000
parents 6cd47402148f
children b1a3d9055662
comparison
equal deleted inserted replaced
5524:8c0e5dc34824 5525:26b5d9bc2985
778 778
779 if (ps_recvpsmsg(ctx, ctx->ps_data_fd, ps_root_dispatchcb, ctx) == -1) 779 if (ps_recvpsmsg(ctx, ctx->ps_data_fd, ps_root_dispatchcb, ctx) == -1)
780 logerr(__func__); 780 logerr(__func__);
781 } 781 }
782 782
783 static void
784 ps_root_syslog(void *arg)
785 {
786 struct dhcpcd_ctx *ctx = arg;
787
788 if (loghandlesyslogfd(ctx->ps_syslog_fd) == -1)
789 logerr(__func__);
790 }
791
783 pid_t 792 pid_t
784 ps_root_start(struct dhcpcd_ctx *ctx) 793 ps_root_start(struct dhcpcd_ctx *ctx)
785 { 794 {
786 int fd[2]; 795 int logfd[2], datafd[2];
787 pid_t pid; 796 pid_t pid;
788 797
789 if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, fd) == -1) 798 if (xsocketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, logfd) == -1)
790 return -1;
791 if (ps_setbuf_fdpair(fd) == -1)
792 return -1; 799 return -1;
793 #ifdef PRIVSEP_RIGHTS 800 #ifdef PRIVSEP_RIGHTS
794 if (ps_rights_limit_fdpair(fd) == -1) 801 if (ps_rights_limit_fdpair(logfd) == -1)
802 return -1;
803 #endif
804
805 if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CXNB, 0, datafd) == -1)
806 return -1;
807 if (ps_setbuf_fdpair(datafd) == -1)
808 return -1;
809 #ifdef PRIVSEP_RIGHTS
810 if (ps_rights_limit_fdpair(datafd) == -1)
795 return -1; 811 return -1;
796 #endif 812 #endif
797 813
798 pid = ps_dostart(ctx, &ctx->ps_root_pid, &ctx->ps_root_fd, 814 pid = ps_dostart(ctx, &ctx->ps_root_pid, &ctx->ps_root_fd,
799 ps_root_recvmsg, NULL, ctx, 815 ps_root_recvmsg, NULL, ctx,
800 ps_root_startcb, ps_root_signalcb, 0); 816 ps_root_startcb, ps_root_signalcb, 0);
801 817
802 if (pid == 0) { 818 if (pid == 0) {
803 ctx->ps_data_fd = fd[1]; 819 ctx->ps_syslog_fd = logfd[1];
804 close(fd[0]); 820 if (eloop_event_add(ctx->eloop, ctx->ps_syslog_fd,
821 ps_root_syslog, ctx) == -1)
822 return -1;
823 close(logfd[0]);
824 ctx->ps_data_fd = datafd[1];
825 close(datafd[0]);
805 return 0; 826 return 0;
806 } else if (pid == -1) 827 } else if (pid == -1)
807 return -1; 828 return -1;
808 829
809 ctx->ps_data_fd = fd[0]; 830 logsetsyslogfd(logfd[0]);
810 close(fd[1]); 831 close(logfd[1]);
832
833 ctx->ps_data_fd = datafd[0];
834 close(datafd[1]);
811 if (eloop_event_add(ctx->eloop, ctx->ps_data_fd, 835 if (eloop_event_add(ctx->eloop, ctx->ps_data_fd,
812 ps_root_dispatch, ctx) == -1) 836 ps_root_dispatch, ctx) == -1)
813 return -1; 837 return -1;
814 838
815 if ((ctx->ps_eloop = eloop_new()) == NULL) 839 if ((ctx->ps_eloop = eloop_new()) == NULL)