From 7280e46aa53ae169a7753d02328ff2c37a25e344 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Sun, 17 May 2026 00:24:57 +0100 Subject: [PATCH] Check for too-small packets in relay_upstream6() Before this fix, the code could read a couple of bytes beyond valid data when an invalid too-short packet was recieved. Thanks to Sokhna Walo DIAKHATE for the bug report. --- src/rfc3315.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/rfc3315.c b/src/rfc3315.c index 9897369..43484fb 100644 --- a/src/rfc3315.c +++ b/src/rfc3315.c @@ -2164,12 +2164,12 @@ static unsigned int opt6_uint(unsigned char *opt, int offset, int size) return ret; } +/* return 0 if we're not configured to relay. */ int relay_upstream6(int iface_index, ssize_t sz, struct in6_addr *peer_address, u32 scope_id, time_t now) { unsigned char *header; unsigned char *inbuff = daemon->dhcp_packet.iov_base; - int msg_type = *inbuff; int hopcount, o; struct in6_addr multicast; unsigned int maclen, mactype; @@ -2186,10 +2186,22 @@ int relay_upstream6(int iface_index, ssize_t sz, inet_pton(AF_INET6, ALL_SERVERS, &multicast); get_client_mac(peer_address, scope_id, mac, &maclen, &mactype, now); + + /* We need at least four bytes for valid client/server message + (type, and transaction ID) A relay-originated message needs more. */ + if (sz < 4) + return 1; - /* Get hop count from nested relayed message */ - if (msg_type == DHCP6RELAYFORW) - hopcount = *((unsigned char *)inbuff+1) + 1; + if (inbuff[0] == DHCP6RELAYFORW) + { + /* must have at least msg_type+hopcount+link_address+peer_address+minimal size option + which is 1 + 1 + 16 + 16 + 2 + 2 = 38 */ + if (sz < 38) + return 1; + + /* Get hop count from nested relayed message. */ + hopcount = inbuff[1] + 1; + } else hopcount = 0;