]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
DHCP: Fix receiving BPF from privsep.
authorRoy Marples <roy@marples.name>
Wed, 5 Feb 2020 15:10:44 +0000 (15:10 +0000)
committerRoy Marples <roy@marples.name>
Wed, 5 Feb 2020 15:10:44 +0000 (15:10 +0000)
src/dhcp.c

index ab0e01912016821dd2575953bc3595be614322a1..25081f20a29547f3d7273f4503527901db6220fc 100644 (file)
@@ -3464,6 +3464,7 @@ dhcp_packet(struct interface *ifp, uint8_t *data, size_t len)
        struct in_addr from;
        size_t udp_len;
        const struct dhcp_state *state = D_CSTATE(ifp);
+       size_t fl = bpf_frame_header_len(ifp);
 
 #ifdef PRIVSEP
        /* Ignore double reads */
@@ -3478,6 +3479,17 @@ dhcp_packet(struct interface *ifp, uint8_t *data, size_t len)
        }
 #endif
 
+       /* Trim frame header */
+       if (fl != 0) {
+               if (len < fl) {
+                       logerrx("%s: %s: short frame header",
+                           __func__, ifp->name);
+                       return;
+               }
+               data += fl;
+               len -= fl;
+       }
+
        /* Validate filter. */
        if (!is_packet_udp_bootp(data, len)) {
 #ifdef BPF_DEBUG
@@ -3510,7 +3522,6 @@ dhcp_readbpf(void *arg)
        uint8_t buf[FRAMELEN_MAX];
        ssize_t bytes;
        struct dhcp_state *state = D_STATE(ifp);
-       ssize_t fl = (ssize_t)bpf_frame_header_len(ifp);
 
        /* Some RAW mechanisms are generic file descriptors, not sockets.
         * This means we have no kernel call to just get one packet,
@@ -3527,12 +3538,7 @@ dhcp_readbpf(void *arg)
                        }
                        break;
                }
-               if (bytes < fl) {
-                       logerrx("%s: %s: short frame header",
-                           __func__, ifp->name);
-                       break;
-               }
-               dhcp_packet(ifp, buf + fl, (size_t)(bytes - fl));
+               dhcp_packet(ifp, buf, (size_t)bytes);
                /* Check we still have a state after processing. */
                if ((state = D_STATE(ifp)) == NULL)
                        break;