From: Roy Marples Date: Thu, 21 May 2020 15:53:54 +0000 (+0100) Subject: privsep: Validate UDP ports X-Git-Tag: v9.1.0~34 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=22a703a7a3ef6b297371a6b61cffacb5556a33f9;p=thirdparty%2Fdhcpcd.git privsep: Validate UDP ports Just like we filter the ioctls. --- diff --git a/src/privsep-inet.c b/src/privsep-inet.c index bc8a3974..c5233024 100644 --- a/src/privsep-inet.c +++ b/src/privsep-inet.c @@ -200,6 +200,25 @@ ps_inet_startcb(void *arg) 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 @@ ps_inet_sendmsg(struct dhcpcd_ctx *ctx, 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 @@ ps_inet_sendmsg(struct dhcpcd_ctx *ctx, #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 diff --git a/src/privsep-root.c b/src/privsep-root.c index d58d282f..36e1ec1a 100644 --- a/src/privsep-root.c +++ b/src/privsep-root.c @@ -434,7 +434,7 @@ ps_root_recvmsgcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg) 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 @@ ps_root_recvmsgcb(void *arg, struct ps_msghdr *psm, struct msghdr *msg) if (psm->ps_cmd & PS_STOP && psp == NULL) return 0; - /* All these should just be PS_START */ switch (cmd) { #ifdef INET #ifdef ARP