]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
privsep: Validate UDP ports
authorRoy Marples <roy@marples.name>
Thu, 21 May 2020 15:53:54 +0000 (16:53 +0100)
committerRoy Marples <roy@marples.name>
Thu, 21 May 2020 15:53:54 +0000 (16:53 +0100)
Just like we filter the ioctls.

src/privsep-inet.c
src/privsep-root.c

index bc8a39744deaf87f1e14c76c1a683549f05f9e3d..c5233024c08c31f8450c345aeb2248475ad6ca66 100644 (file)
@@ -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
index d58d282fcb75ca965d4764c7b7f55732f3c7aef9..36e1ec1a0fdb31321df24455708b29e4b47dbd52 100644 (file)
@@ -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