]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Validate UDP better by ensuring data len is not bigger than our struct
authorRoy Marples <roy@marples.name>
Sat, 28 Feb 2009 08:59:48 +0000 (08:59 +0000)
committerRoy Marples <roy@marples.name>
Sat, 28 Feb 2009 08:59:48 +0000 (08:59 +0000)
and that the claimed length by the header is not greater than our length.
Thanks to Michael Olney.

dhcpcd.c
net.c
net.h

index a937335dd75b59da8d014caead8ac24fa9bccc8a..a36a49932645d93e34d4be163976746aa5a8fb5d 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -606,7 +606,7 @@ handle_dhcp_packet(void *arg)
                    packet, udp_dhcp_len);
                if (bytes == 0 || bytes == -1)
                        break;
-               if (valid_udp_packet(packet) == -1)
+               if (valid_udp_packet(packet, bytes) == -1)
                        continue;
                bytes = get_udp_data(&pp, packet);
                if ((size_t)bytes > sizeof(*dhcp)) {
diff --git a/net.c b/net.c
index 0db55c0fb2f9f0179dc05fa00c836fc55f22a400..f624a5f82f337c9630a2e47fec3f45e9a7bc3a68 100644 (file)
--- a/net.c
+++ b/net.c
@@ -639,18 +639,26 @@ get_udp_data(const uint8_t **data, const uint8_t *udp)
 }
 
 int
-valid_udp_packet(const uint8_t *data)
+valid_udp_packet(const uint8_t *data, size_t data_len)
 {
        struct udp_dhcp_packet packet;
        uint16_t bytes, udpsum;
 
-       memcpy(&packet, data, sizeof(packet));
+       if (data_len > sizeof(packet)) {
+               errno = EINVAL;
+               return -1;
+       }
+       memcpy(&packet, data, data_len);
        if (checksum(&packet.ip, sizeof(packet.ip)) != 0) {
                errno = EINVAL;
                return -1;
        }
 
        bytes = ntohs(packet.ip.ip_len);
+       if (data_len < bytes) {
+               errno = EINVAL;
+               return -1;
+       }
        udpsum = packet.udp.uh_sum;
        packet.udp.uh_sum = 0;
        packet.ip.ip_hl = 0;
@@ -668,4 +676,3 @@ valid_udp_packet(const uint8_t *data)
 
        return 0;
 }
-
diff --git a/net.h b/net.h
index b6ee44dda7df1e701da9fff463aaae5de2bfa8fb..3ebc454aa063b07af44e2daf352261665277db49 100644 (file)
--- a/net.h
+++ b/net.h
@@ -137,7 +137,7 @@ const size_t udp_dhcp_len;
 ssize_t make_udp_packet(uint8_t **, const uint8_t *, size_t,
     struct in_addr, struct in_addr);
 ssize_t get_udp_data(const uint8_t **, const uint8_t *);
-int valid_udp_packet(const uint8_t *);
+int valid_udp_packet(const uint8_t *, size_t);
 
 int open_socket(struct interface *, int);
 ssize_t send_packet(const struct interface *, struct in_addr,