summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Wagner <wagi@monom.org>2023-04-11 08:12:56 +0200
committerDaniel Wagner <wagi@monom.org>2023-04-11 08:12:56 +0200
commit99e2c16ea1cced34a5dc450d76287a1c3e762138 (patch)
tree3241fecab3526ba395c7376848c7fd21418fc612
parent9971144ae862e83f1f5d8cb84c0b62f2542dcdec (diff)
downloadconnman-99e2c16ea1cced34a5dc450d76287a1c3e762138.tar.gz
gdhcp: Verify and sanitize packet length first
Avoid overwriting the read packet length after the initial test. Thus move all the length checks which depends on the total length first and do not use the total lenght from the IP packet afterwards. Fixes CVE-2023-28488 Reported by Polina Smirnova <moe.hwr@gmail.com>
-rw-r--r--gdhcp/client.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/gdhcp/client.c b/gdhcp/client.c
index 7efa7e45..82017692 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -1319,9 +1319,9 @@ static bool sanity_check(struct ip_udp_dhcp_packet *packet, int bytes)
static int dhcp_recv_l2_packet(struct dhcp_packet *dhcp_pkt, int fd,
struct sockaddr_in *dst_addr)
{
- int bytes;
struct ip_udp_dhcp_packet packet;
uint16_t check;
+ int bytes, tot_len;
memset(&packet, 0, sizeof(packet));
@@ -1329,15 +1329,17 @@ static int dhcp_recv_l2_packet(struct dhcp_packet *dhcp_pkt, int fd,
if (bytes < 0)
return -1;
- if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp)))
- return -1;
-
- if (bytes < ntohs(packet.ip.tot_len))
+ tot_len = ntohs(packet.ip.tot_len);
+ if (bytes > tot_len) {
+ /* ignore any extra garbage bytes */
+ bytes = tot_len;
+ } else if (bytes < tot_len) {
/* packet is bigger than sizeof(packet), we did partial read */
return -1;
+ }
- /* ignore any extra garbage bytes */
- bytes = ntohs(packet.ip.tot_len);
+ if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp)))
+ return -1;
if (!sanity_check(&packet, bytes))
return -1;