From: Roy Marples Date: Sat, 28 Feb 2009 08:59:48 +0000 (+0000) Subject: Validate UDP better by ensuring data len is not bigger than our struct X-Git-Tag: v5.0.0~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e103c79fca52c8f8eeb651e7f0e273000fe68819;p=thirdparty%2Fdhcpcd.git Validate UDP better by ensuring data len is not bigger than our struct and that the claimed length by the header is not greater than our length. Thanks to Michael Olney. --- diff --git a/dhcpcd.c b/dhcpcd.c index a937335d..a36a4993 100644 --- 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 0db55c0f..f624a5f8 100644 --- 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 b6ee44dd..3ebc454a 100644 --- 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,