changeset 5332:b22045bba8b9 draft

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.
author Roy Marples <roy@marples.name>
date Wed, 10 Jun 2020 04:57:02 +0100
parents d075e31eb148
children 4fb2ba0739f0
files configure src/control.c src/dhcpcd.h src/privsep-control.c src/privsep.c src/privsep.h
diffstat 6 files changed, 38 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/configure	Tue Jun 09 22:39:05 2020 +0100
+++ b/configure	Wed Jun 10 04:57:02 2020 +0100
@@ -545,6 +545,15 @@
 	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 @@
 	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 @@
 $CC --version | $SED -e '1!d'
 
 if [ "$PRIVSEP" = yes ]; then
-	PRIVSEP_CONTROLLER=true
 	printf "Testing for capsicum ... "
 	cat <<EOF >_capsicum.c
 #include <sys/capsicum.h>
@@ -636,7 +644,6 @@
 	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 @@
 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
--- a/src/control.c	Tue Jun 09 22:39:05 2020 +0100
+++ b/src/control.c	Wed Jun 10 04:57:02 2020 +0100
@@ -79,7 +79,7 @@
 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 @@
 control_delete(struct fd_list *fd)
 {
 
-#ifdef PRIVSEP_CONTROLLER
+#ifdef PRIVSEP
 	if (IN_PRIVSEP_SE(fd->ctx))
 		return;
 #endif
@@ -120,7 +120,7 @@
 		return;
 	}
 
-#ifdef PRIVSEP_CONTROLLER
+#ifdef PRIVSEP
 	if (IN_PRIVSEP(fd->ctx)) {
 		ssize_t err;
 
@@ -236,7 +236,7 @@
 	    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 @@
 {
 	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_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 @@
 		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__);
--- a/src/dhcpcd.h	Tue Jun 09 22:39:05 2020 +0100
+++ b/src/dhcpcd.h	Wed Jun 10 04:57:02 2020 +0100
@@ -209,13 +209,11 @@
 	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
--- a/src/privsep-control.c	Tue Jun 09 22:39:05 2020 +0100
+++ b/src/privsep-control.c	Wed Jun 10 04:57:02 2020 +0100
@@ -277,6 +277,15 @@
 	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;
 }
 
--- a/src/privsep.c	Tue Jun 09 22:39:05 2020 +0100
+++ b/src/privsep.c	Wed Jun 10 04:57:02 2020 +0100
@@ -129,12 +129,12 @@
 		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 @@
 	/* 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 @@
 		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 @@
 		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 @@
 	    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)
--- a/src/privsep.h	Tue Jun 09 22:39:05 2020 +0100
+++ b/src/privsep.h	Wed Jun 10 04:57:02 2020 +0100
@@ -158,14 +158,12 @@
 };
 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 *);