From: Roy Marples Date: Wed, 10 Jun 2020 03:57:02 +0000 (+0100) Subject: privsep: control proxy is no longer optional X-Git-Tag: v9.1.2~25 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7cb1e26d9e4943eb7ef450ed3aeeadf5a70e3227;p=thirdparty%2Fdhcpcd.git privsep: control proxy is no longer optional It's required for pledge. It *could* be optional for capsicum but I'd like to try and keep the sandboxing the same for now. --- diff --git a/configure b/configure index 4c947841..87fb6b25 100755 --- a/configure +++ b/configure @@ -545,6 +545,15 @@ if [ -z "$AUTH" -o "$AUTH" = yes ]; then echo "SRCS+= auth.c" >>$CONFIG_MK fi +if [ -z "$EMBEDDED" -o "$EMBEDDED" = yes ]; then + echo "$DHCPCD_DEFS will be embedded in dhcpcd itself" + echo "DHCPCD_SRCS+= dhcpcd-embedded.c" >>$CONFIG_MK +else + echo "$DHCPCD_DEFS will be installed to $LIBEXECDIR" + echo "CPPFLAGS+= -DEMBEDDED_CONFIG=\\\"$LIBEXECDIR/dhcpcd-definitions.conf\\\"" >>$CONFIG_MK + echo "EMBEDDEDINSTALL= _embeddedinstall" >>$CONFIG_MK +fi + if [ -z "$PRIVSEP" ]; then # privilege separation works fine .... except on Solaris case "$OS" in @@ -580,8 +589,8 @@ if [ "$PRIVSEP" = yes ]; then echo "#ifndef PRIVSEP_USER" >>$CONFIG_H echo "#define PRIVSEP_USER \"$PRIVSEP_USER\"" >>$CONFIG_H echo "#endif" >>$CONFIG_H - echo "PRIVSEP_SRCS= privsep.c privsep-root.c privsep-inet.c" \ - >>$CONFIG_MK + echo "PRIVSEP_SRCS= privsep.c privsep-root.c" >>$CONFIG_MK + echo "PRIVSEP_SRCS+= privsep-control.c privsep-inet.c" >>$CONFIG_MK if [ -z "$INET" ] || [ "$INET" = yes ]; then echo "PRIVSEP_SRCS+= privsep-bpf.c" >>$CONFIG_MK fi @@ -625,7 +634,6 @@ fi $CC --version | $SED -e '1!d' if [ "$PRIVSEP" = yes ]; then - PRIVSEP_CONTROLLER=true printf "Testing for capsicum ... " cat <_capsicum.c #include @@ -636,7 +644,6 @@ EOF if $XCC _capsicum.c -o _capsicum 2>&3; then echo "yes" echo "#define HAVE_CAPSICUM" >>$CONFIG_H - PRIVSEP_CONTROLLER=false else echo "no" fi @@ -651,26 +658,11 @@ int main(void) { EOF if $XCC _pledge.c -o _pledge 2>&3; then echo "yes" - echo "#define HAVE_PLEDGE" >>$CONFIG_H - PRIVSEP_CONTROLLER=false + echo "#define HAVE_PLEDGE" >>$CONFIG_H else echo "no" fi rm -f _pledge.c _pledge - - if $PRIVSEP_CONTROLLER; then - echo "#define PRIVSEP_CONTROLLER" >>$CONFIG_H - echo "PRIVSEP_SRCS+= privsep-control.c" >>$CONFIG_MK - fi -fi - -if [ -z "$EMBEDDED" -o "$EMBEDDED" = yes ]; then - echo "$DHCPCD_DEFS will be embedded in dhcpcd itself" - echo "DHCPCD_SRCS+= dhcpcd-embedded.c" >>$CONFIG_MK -else - echo "$DHCPCD_DEFS will be installed to $LIBEXECDIR" - echo "CPPFLAGS+= -DEMBEDDED_CONFIG=\\\"$LIBEXECDIR/dhcpcd-definitions.conf\\\"" >>$CONFIG_MK - echo "EMBEDDEDINSTALL= _embeddedinstall" >>$CONFIG_MK fi if [ "$OS" = linux ]; then diff --git a/src/control.c b/src/control.c index 2977423e..e704df7f 100644 --- a/src/control.c +++ b/src/control.c @@ -79,7 +79,7 @@ void control_free(struct fd_list *fd) { -#ifdef PRIVSEP_CONTROLLER +#ifdef PRIVSEP if (fd->ctx->ps_control_client == fd) fd->ctx->ps_control_client = NULL; #endif @@ -94,7 +94,7 @@ void control_delete(struct fd_list *fd) { -#ifdef PRIVSEP_CONTROLLER +#ifdef PRIVSEP if (IN_PRIVSEP_SE(fd->ctx)) return; #endif @@ -120,7 +120,7 @@ control_handle_data(void *arg) return; } -#ifdef PRIVSEP_CONTROLLER +#ifdef PRIVSEP if (IN_PRIVSEP(fd->ctx)) { ssize_t err; @@ -236,7 +236,7 @@ control_handle1(struct dhcpcd_ctx *ctx, int lfd, unsigned int fd_flags) fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) goto error; -#ifdef PRIVSEP_CONTROLLER +#ifdef PRIVSEP if (IN_PRIVSEP(ctx) && !IN_PRIVSEP_SE(ctx)) ; else @@ -357,7 +357,7 @@ control_start(struct dhcpcd_ctx *ctx, const char *ifname, sa_family_t family) { int fd; -#ifdef PRIVSEP_CONTROLLER +#ifdef PRIVSEP if (IN_PRIVSEP_SE(ctx)) { make_path(ctx->control_sock, sizeof(ctx->control_sock), ifname, family); @@ -410,7 +410,7 @@ control_stop(struct dhcpcd_ctx *ctx) control_free(l); } -#ifdef PRIVSEP_CONTROLLER +#ifdef PRIVSEP if (IN_PRIVSEP_SE(ctx)) { if (ps_root_unlink(ctx, ctx->control_sock) == -1) retval = -1; @@ -525,7 +525,7 @@ control_writeone(void *arg) return; eloop_event_remove_writecb(fd->ctx->eloop, fd->fd); -#ifdef PRIVSEP_CONTROLLER +#ifdef PRIVSEP if (IN_PRIVSEP_SE(fd->ctx) && !(fd->flags & FD_LISTEN)) { if (ps_ctl_sendeof(fd) == -1) logerr(__func__); diff --git a/src/dhcpcd.h b/src/dhcpcd.h index 7ab95e86..b165f5fc 100644 --- a/src/dhcpcd.h +++ b/src/dhcpcd.h @@ -209,13 +209,11 @@ struct dhcpcd_ctx { struct ps_process_head ps_processes; /* List of spawned processes */ pid_t ps_inet_pid; int ps_inet_fd; /* Network Proxy commands and data */ -#ifdef PRIVSEP_CONTROLLER pid_t ps_control_pid; - int ps_control_fd; - int ps_control_data_fd; - struct fd_list *ps_control; - struct fd_list *ps_control_client; -#endif + int ps_control_fd; /* Control Proxy - generic listener */ + int ps_control_data_fd; /* Control Proxy - data query */ + struct fd_list *ps_control; /* Queue for the above */ + struct fd_list *ps_control_client; /* Queue for the above */ #endif #ifdef INET diff --git a/src/privsep-control.c b/src/privsep-control.c index bd74198e..7dfc0ad7 100644 --- a/src/privsep-control.c +++ b/src/privsep-control.c @@ -277,6 +277,15 @@ ps_ctl_start(struct dhcpcd_ctx *ctx) if (eloop_event_add(ctx->eloop, ctx->ps_control->fd, ps_ctl_listen, ctx) == -1) return -1; + +#ifdef HAVE_CAPSICUM + if (cap_enter() == -1 && errno != ENOSYS) + logerr("%s: cap_enter", __func__); +#endif +#ifdef HAVE_PLEDGE + if (pledge("stdio inet", NULL) == -1) + logerr("%s: pledge", __func__); +#endif return 0; } diff --git a/src/privsep.c b/src/privsep.c index c93f00b0..d957946d 100644 --- a/src/privsep.c +++ b/src/privsep.c @@ -129,12 +129,12 @@ ps_dropprivs(struct dhcpcd_ctx *ctx) return -1; } - struct rlimit rzero = { .rlim_cur = 0, .rlim_max = 0 }; - #if defined(HAVE_CAPSICUM) || defined(HAVE_PLEDGE) /* These sandbox technologies do not work well with * resource limits. */ #else + struct rlimit rzero = { .rlim_cur = 0, .rlim_max = 0 }; + if (ctx->ps_control_pid != getpid()) { /* Prohibit new files, sockets, etc */ #if defined(__linux__) || defined(__sun) @@ -444,7 +444,7 @@ ps_start(struct dhcpcd_ctx *ctx) /* No point in spawning the generic network listener if we're * not going to use it. */ if (!(ctx->options & (DHCPCD_MASTER | DHCPCD_IPV6))) - goto started; + goto started_net; switch (pid = ps_inet_start(ctx)) { case -1: @@ -457,8 +457,7 @@ ps_start(struct dhcpcd_ctx *ctx) logdebugx("spawned network proxy on PID %d", pid); } -started: -#ifdef PRIVSEP_CONTROLLER +started_net: if (!(ctx->options & DHCPCD_TEST)) { switch (pid = ps_ctl_start(ctx)) { case -1: @@ -466,10 +465,9 @@ started: case 0: return 0; default: - logdebugx("spawned controller on PID %d", pid); + logdebugx("spawned controller proxy on PID %d", pid); } } -#endif #ifdef ARC4RANDOM_H /* Seed the random number generator early incase it needs /dev/urandom @@ -524,11 +522,9 @@ ps_stop(struct dhcpcd_ctx *ctx) ctx->eloop == NULL) return 0; -#ifdef PRIVSEP_CONTROLLER r = ps_ctl_stop(ctx); if (r != 0) ret = r; -#endif r = ps_inet_stop(ctx); if (r != 0) diff --git a/src/privsep.h b/src/privsep.h index 2bc9bac3..877f1527 100644 --- a/src/privsep.h +++ b/src/privsep.h @@ -158,14 +158,12 @@ struct ps_process { }; TAILQ_HEAD(ps_process_head, ps_process); +#include "privsep-control.h" #include "privsep-inet.h" #include "privsep-root.h" #ifdef INET #include "privsep-bpf.h" #endif -#ifdef PRIVSEP_CONTROLLER -#include "privsep-control.h" -#endif int ps_init(struct dhcpcd_ctx *); int ps_dropprivs(struct dhcpcd_ctx *);