changeset 5253:7a0d53acbb06 draft

privsep: Validate UDP ports Just like we filter the ioctls.
author Roy Marples <roy@marples.name>
date Thu, 21 May 2020 16:53:54 +0100
parents bae9ab6cd868
children 2b7aae4f02f0
files src/privsep-inet.c src/privsep-root.c
diffstat 2 files changed, 24 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/privsep-inet.c	Thu May 21 16:30:08 2020 +0100
+++ b/src/privsep-inet.c	Thu May 21 16:53:54 2020 +0100
@@ -200,6 +200,25 @@
 	return ret;
 }
 
+static bool
+ps_inet_udpports(struct msghdr *msg, uint16_t sport, uint16_t dport)
+{
+	struct udphdr udp;
+	struct iovec *iov = msg->msg_iov;
+
+	if (msg->msg_iovlen == 0 || iov->iov_len < sizeof(udp)) {
+		errno = EINVAL;
+		return false;
+	}
+
+	memcpy(&udp, iov->iov_base, sizeof(udp));
+	if (udp.uh_sport != htons(sport) || udp.uh_dport != htons(dport)) {
+		errno = EPERM;
+		return false;
+	}
+	return true;
+}
+
 static ssize_t
 ps_inet_sendmsg(struct dhcpcd_ctx *ctx,
     struct ps_msghdr *psm, struct msghdr *msg)
@@ -216,6 +235,8 @@
 	switch (psm->ps_cmd) {
 #ifdef INET
 	case PS_BOOTP:
+		if (!ps_inet_udpports(msg, BOOTPC, BOOTPS))
+			return -1;
 		s = ctx->udp_wfd;
 		break;
 #endif
@@ -226,6 +247,8 @@
 #endif
 #ifdef DHCP6
 	case PS_DHCP6:
+		if (!ps_inet_udpports(msg, DHCP6_CLIENT_PORT,DHCP6_SERVER_PORT))
+			return -1;
 		s = ctx->dhcp6_wfd;
 		break;
 #endif
--- a/src/privsep-root.c	Thu May 21 16:30:08 2020 +0100
+++ b/src/privsep-root.c	Thu May 21 16:53:54 2020 +0100
@@ -434,7 +434,7 @@
 	uint8_t buf[PS_BUFLEN];
 	time_t mtime;
 	ssize_t err;
-	bool free_rdata= false;
+	bool free_rdata = false;
 
 	cmd = (uint16_t)(psm->ps_cmd & ~(PS_START | PS_STOP));
 	psp = ps_findprocess(ctx, &psm->ps_id);
@@ -458,7 +458,6 @@
 	if (psm->ps_cmd & PS_STOP && psp == NULL)
 		return 0;
 
-	/* All these should just be PS_START */
 	switch (cmd) {
 #ifdef INET
 #ifdef ARP