changeset 5242:0dd9b7f7cf6b draft

privsep: Ensure we don't scribble garbage to BPF Well, it's not garbage, it's a privsep IPC message telling us to start BPF which the BPF process should not have recieved! Add code to ensure this cannot happen.
author Roy Marples <roy@marples.name>
date Wed, 20 May 2020 15:44:19 +0000
parents 989bcc6c8e70
children 0d5671483751
files src/privsep-bpf.c src/privsep-root.c
diffstat 2 files changed, 22 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/privsep-bpf.c	Wed May 20 15:43:44 2020 +0000
+++ b/src/privsep-bpf.c	Wed May 20 15:44:19 2020 +0000
@@ -92,11 +92,28 @@
 }
 
 static ssize_t
-ps_bpf_recvmsgcb(void *arg, __unused struct ps_msghdr *psm, struct msghdr *msg)
+ps_bpf_recvmsgcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg)
 {
 	struct ps_process *psp = arg;
 	struct iovec *iov = msg->msg_iov;
 
+#ifdef PRIVSEP_DEBUG
+	logerrx("%s: IN cmd %x, psp %p", __func__, psm->ps_cmd, psp);
+#endif
+
+	switch(psm->ps_cmd) {
+#ifdef ARP
+	case PS_BPF_ARP:	/* FALLTHROUGH */
+#endif
+	case PS_BPF_BOOTP:
+		break;
+	default:
+		/* IPC failure, we should not be processing any commands
+		 * at this point!/ */
+		errno = EINVAL;
+		return -1;
+	}
+
 	return bpf_send(psp->psp_bpf, psp->psp_proto,
 	    iov->iov_base, iov->iov_len);
 }
@@ -106,13 +123,6 @@
 {
 	struct ps_process *psp = arg;
 
-	/*
-	 * OpenBSD-6.6 at least will return EPERM here for every
-	 * BOOTP sent except for the first one.
-	 * However with wih EPERM, the BOOTP message is *still* sent.
-	 * This means the BPF write filter isn't working as it should.
-	 * On FreeBSD it works fine.
-	 */
 	if (ps_recvpsmsg(psp->psp_ctx, psp->psp_fd,
 	    ps_bpf_recvmsgcb, arg) == -1)
 		logerr(__func__);
--- a/src/privsep-root.c	Wed May 20 15:43:44 2020 +0000
+++ b/src/privsep-root.c	Wed May 20 15:44:19 2020 +0000
@@ -409,8 +409,10 @@
 
 			ps_freeprocess(psp);
 			return ret;
-		}
-		return ps_sendpsmmsg(ctx, psp->psp_fd, psm, msg);
+		} else if (!(psm->ps_cmd & PS_START))
+			return ps_sendpsmmsg(ctx, psp->psp_fd, psm, msg);
+		/* Process has already started .... */
+		return 0;
 	}
 
 	if (psm->ps_cmd & PS_STOP && psp == NULL)