summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2009-02-28 08:59:48 +0000
committerRoy Marples <roy@marples.name>2009-02-28 08:59:48 +0000
commite103c79fca52c8f8eeb651e7f0e273000fe68819 (patch)
tree5e9fabd145e2fc05d04e5db152a60dabb51a261c
parente095a6ebb581216ef8369d1e468a6682332498a7 (diff)
downloaddhcpcd-e103c79fca52c8f8eeb651e7f0e273000fe68819.tar.xz
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.
-rw-r--r--dhcpcd.c2
-rw-r--r--net.c13
-rw-r--r--net.h2
3 files changed, 12 insertions, 5 deletions
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,