dhcrelay: Add security patches for equilibrium. This commit introduces a comprehensive set of 12 patches for the phosphor-ipmi-host package, resolving 12 identified Buganizer issues. The patches cover: - Fix off-by-one buffer overflow in MRns_name_uncompress_list - Fix out-of-bounds read in delete_hash_entry via non-string keys - Fix Null Pointer Dereference in omapi_auth_key_destroy - Fix NULL pointer dereferences in hash table operations - Fix integer wrap-around logic flaw in converted_length - Fix heap buffer underflow in parse_numeric_aggregate - Fix out-of-bounds read in MRns_name_compress_list - Fix stack buffer overflow and integer underflow in concat_dclists - Fix stack buffer overflow in hh buffer in send_packet - Fix uninitialized memory leak in add_relay_agent_options - Fix stack buffer overflow in send_packet - Improve PRNG seeding in dhcp_context_create Each logical fix is isolated into an individual patch file for better traceability and maintainability. Tested: 1. Verify DHCP works with mimik and verified pcap https://screenshot.googleplex.com/6rvfikntihDXwWk 2. Reserved a tpu machine, flashed host and accel tray BMCs, wiped rwfs, setup dhcp lease, verified dhcp worked on tray and host BMCs. platform5: https://fusion2.corp.google.com/6d5c54b2-ba8a-353a-ae67-e49447a1c018 platform15: https://fusion2.corp.google.com/439eda16-e2be-3633-8c97-ae64b9989ed9 platform18: https://fusion2.corp.google.com/cf27a09d-03fa-326e-89e0-39ea240e1e0a platform17: https://fusion2.corp.google.com/3a905c12-ddb4-3bb3-8fe7-476eac4a74a8 platform11+ext: https://fusion2.corp.google.com/6c1c5c0c-23cf-3de6-8b5f-74a71418e035 platform11: https://fusion2.corp.google.com/bc4ee4e6-9fa6-30e3-b92e-14c785bac902 ---------------------------------------- Google-Bug-Id: 510454086 Google-Bug-Id: 510453873 Google-Bug-Id: 510453866 Google-Bug-Id: 510453473 Google-Bug-Id: 510454983 Google-Bug-Id: 510454798 Google-Bug-Id: 510454409 Google-Bug-Id: 510454340 Google-Bug-Id: 510454261 Google-Bug-Id: 510453307 Google-Bug-Id: 510454125 Google-Bug-Id: 510454046 Change-Id: If88b70f36fc2e39da67d12bd5aab6b83dbc0cf6e Signed-off-by: Chris Rauer <crauer@google.com> Platforms-Affected: ALL (cherry picked from commit f2bc56d57b29d75d8eae95e88326f6cf7db6c16d)
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0001-dhcp-relay-Improve-PRNG-seeding-in-dhcp_context_crea.patch b/recipes-connectivity/dhcp/dhcp-relay/0001-dhcp-relay-Improve-PRNG-seeding-in-dhcp_context_crea.patch new file mode 100644 index 0000000..7e126d6 --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0001-dhcp-relay-Improve-PRNG-seeding-in-dhcp_context_crea.patch
@@ -0,0 +1,51 @@ +From f4eb5eafd5fc32aa5c6b36f2f6158ecc941ca25d Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Wed, 20 May 2026 21:52:56 +0000 +Subject: [PATCH 01/12] [dhcp-relay] Improve PRNG seeding in + dhcp_context_create + +Seeding the PRNG with only cur_tv.tv_sec (seconds since epoch) is weak and +predictable, especially if the daemon start time can be estimated. + +This CL improves the seeding by: +1. Attempting to read a seed from the system random device (ISC_PATH_RANDOMDEV, e.g., /dev/random) if available. +2. Falling back to a combination of tv_sec, tv_usec, and getpid() if the random device is not available or fails. + +This provides much stronger entropy for the PRNG initialized in dhcp_context_create. + +BUG=510454086 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + omapip/isclib.c | 15 ++++++++++++++- + 1 file changed, 14 insertions(+), 1 deletion(-) + +diff --git a/omapip/isclib.c b/omapip/isclib.c +index 2293cbe4..e1cc5abf 100644 +--- a/omapip/isclib.c ++++ b/omapip/isclib.c +@@ -188,7 +188,20 @@ dhcp_context_create(int flags, + + /* get the current time for use as the random seed */ + gettimeofday(&cur_tv, (struct timezone *)0); +- isc_random_seed(cur_tv.tv_sec); ++ ++ unsigned int seed = 0; ++ size_t nrnd = 0; ++#ifdef ISC_PATH_RANDOMDEV ++ FILE *frnd = fopen(ISC_PATH_RANDOMDEV, "r"); ++ if (frnd) { ++ nrnd = fread(&seed, sizeof(seed), 1, frnd); ++ fclose(frnd); ++ } ++#endif ++ if (!nrnd) { ++ seed = (unsigned int)(cur_tv.tv_sec ^ cur_tv.tv_usec ^ getpid()); ++ } ++ isc_random_seed(seed); + + /* we need to create the memory context before + * the lib inits in case we aren't doing NSUPDATE +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0002-dhcp-relay-Fix-stack-buffer-overflow-in-send_packet.patch b/recipes-connectivity/dhcp/dhcp-relay/0002-dhcp-relay-Fix-stack-buffer-overflow-in-send_packet.patch new file mode 100644 index 0000000..78aea1d --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0002-dhcp-relay-Fix-stack-buffer-overflow-in-send_packet.patch
@@ -0,0 +1,119 @@ +From ad850938160b26db29c5c1d6e4fa6711b3e677e4 Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Wed, 20 May 2026 23:20:45 +0000 +Subject: [PATCH 02/12] [dhcp-relay] Fix stack buffer overflow in send_packet + +A stack buffer overflow vulnerability existed in send_packet implementations +that copy the DHCP payload into a local stack buffer (lpf.c, dlpi.c, nit.c). +With Option 82 (Relay Agent Options) or other options, the DHCP payload +length could grow up to ~1500 bytes, which when combined with headers +exceeded the 1536-byte stack buffer 'ih'. + +This CL fixes the vulnerability by: +1. Increasing the 'ih' stack buffer size to 65536 bytes (maximum IP packet size). +2. Adding run-time size checks before copying headers and payload to prevent buffer overflow. + +Vulnerable implementations in common/lpf.c, common/dlpi.c, and common/nit.c have been fixed. +Other implementations using writev/iovec (bpf.c, upf.c, raw.c) or direct sendto (socket.c) are unaffected. + +BUG=510453873 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + common/dlpi.c | 15 ++++++++++++++- + common/lpf.c | 9 ++++++++- + common/nit.c | 9 ++++++++- + 3 files changed, 30 insertions(+), 3 deletions(-) + +diff --git a/common/dlpi.c b/common/dlpi.c +index f2332c0f..003aaa84 100644 +--- a/common/dlpi.c ++++ b/common/dlpi.c +@@ -537,7 +537,7 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) + double hh [32]; + int fudge; + #endif +- double ih [1536 / sizeof (double)]; ++ double ih [65536 / sizeof (double)]; + unsigned char *dbuf = (unsigned char *)ih; + unsigned dbuflen; + unsigned char dstaddr [DLPI_MAXDLADDR]; +@@ -559,8 +559,21 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) + if (dbuflen > sizeof hh) + log_fatal ("send_packet: hh buffer too small.\n"); + fudge = dbuflen % 4; /* IP header must be word-aligned. */ ++ ++ if (dbuflen + fudge + 28 + len > sizeof(ih)) { ++ log_error("send_packet: packet too large (%d > %d)", ++ (int)(dbuflen + fudge + 28 + len), (int)sizeof(ih)); ++ return -1; ++ } ++ + memcpy (dbuf + fudge, (unsigned char *)hh, dbuflen); + dbuflen += fudge; ++#else ++ if (28 + len > sizeof(ih)) { ++ log_error("send_packet: packet too large (%d > %d)", ++ (int)(28 + len), (int)sizeof(ih)); ++ return -1; ++ } + #endif + assemble_udp_ip_header (interface, dbuf, &dbuflen, from.s_addr, + to -> sin_addr.s_addr, to -> sin_port, +diff --git a/common/lpf.c b/common/lpf.c +index bd20b3f5..9be86afb 100644 +--- a/common/lpf.c ++++ b/common/lpf.c +@@ -341,7 +341,7 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) + { + unsigned hbufp = 0, ibufp = 0; + double hh [16]; +- double ih [1536 / sizeof (double)]; ++ double ih [65536 / sizeof (double)]; + unsigned char *buf = (unsigned char *)ih; + int result; + int fudge; +@@ -356,6 +356,13 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) + /* Assemble the headers... */ + assemble_hw_header (interface, (unsigned char *)hh, &hbufp, hto); + fudge = hbufp % 4; /* IP header must be word-aligned. */ ++ ++ if (hbufp + fudge + 28 + len > sizeof(ih)) { ++ log_error("send_packet: packet too large (%d > %d)", ++ (int)(hbufp + fudge + 28 + len), (int)sizeof(ih)); ++ return -1; ++ } ++ + memcpy (buf + fudge, (unsigned char *)hh, hbufp); + ibufp = hbufp + fudge; + assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr, +diff --git a/common/nit.c b/common/nit.c +index ba62488f..42b6c33e 100644 +--- a/common/nit.c ++++ b/common/nit.c +@@ -285,7 +285,7 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) + { + unsigned hbufp, ibufp; + double hh [16]; +- double ih [1536 / sizeof (double)]; ++ double ih [65536 / sizeof (double)]; + unsigned char *buf = (unsigned char *)ih; + struct sockaddr *junk; + struct strbuf ctl, data; +@@ -307,6 +307,13 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) + + /* Assemble the headers... */ + assemble_hw_header (interface, (unsigned char *)junk, &hbufp, hto); ++ ++ if (28 + len > sizeof(ih)) { ++ log_error("send_packet: packet too large (%d > %d)", ++ (int)(28 + len), (int)sizeof(ih)); ++ return -1; ++ } ++ + assemble_udp_ip_header (interface, buf, &ibufp, + from.s_addr, to -> sin_addr.s_addr, + to -> sin_port, (unsigned char *)raw, len); +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0003-dhcp-relay-Fix-uninitialized-memory-leak-in-add_rela.patch b/recipes-connectivity/dhcp/dhcp-relay/0003-dhcp-relay-Fix-uninitialized-memory-leak-in-add_rela.patch new file mode 100644 index 0000000..c0dbf58 --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0003-dhcp-relay-Fix-uninitialized-memory-leak-in-add_rela.patch
@@ -0,0 +1,69 @@ +From bc969db577bd873492930b20ef6443186e7b31d0 Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Wed, 20 May 2026 23:25:44 +0000 +Subject: [PATCH 03/12] [dhcp-relay] Fix uninitialized memory leak in + add_relay_agent_options + +In add_relay_agent_options (relay/dhcrelay.c), the option parsing loop +used 'max' (the grow limit of the packet, which can be up to 1500 bytes) +as the loop boundary instead of the actual received packet 'length'. + +If the received packet was shorter than 'max' and options were parsed +beyond the received length (e.g. if the packet was malformed or DHO_END +was missing/bypassed), the parser would read uninitialized stack memory +from the packet input buffer. If it then copied or processed these +"options", it could leak uninitialized stack garbage over the network. + +This CL fixes the issue by introducing 'parse_limit' (set to packet + length) +and using it as the boundary for the option parsing loop and option size +checks, ensuring we never parse or read beyond the received packet size. +'max' is preserved solely as the limit for growing the packet. + +BUG=510453866 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + relay/dhcrelay.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c +index d9b5719c..e869693e 100644 +--- a/relay/dhcrelay.c ++++ b/relay/dhcrelay.c +@@ -1213,6 +1213,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + int is_dhcp = 0, mms; + unsigned optlen; + u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; ++ const u_int8_t *parse_limit; + int adding_link_select; + + /* If we're not adding agent options to packets, we can skip +@@ -1226,6 +1227,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + return (length); + + max = ((u_int8_t *)packet) + dhcp_max_agent_option_packet_length; ++ parse_limit = ((u_int8_t *)packet) + length; + + /* Add link selection suboption if enabled and we're the first relay */ + adding_link_select = (add_rfc3527_suboption +@@ -1234,7 +1236,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + /* Commence processing after the cookie. */ + sp = op = &packet->options[4]; + +- while (op < max) { ++ while (op < parse_limit) { + switch(*op) { + /* Skip padding... */ + case DHO_PAD: +@@ -1314,7 +1316,7 @@ add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, + * buffer(op[1] is malformed). + */ + nextop = op + op[1] + 2; +- if (nextop > max) ++ if (nextop > parse_limit) + return (0); + + end_pad = NULL; +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0004-dhcp-relay-Fix-stack-buffer-overflow-in-hh-buffer-in.patch b/recipes-connectivity/dhcp/dhcp-relay/0004-dhcp-relay-Fix-stack-buffer-overflow-in-hh-buffer-in.patch new file mode 100644 index 0000000..6e98a23 --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0004-dhcp-relay-Fix-stack-buffer-overflow-in-hh-buffer-in.patch
@@ -0,0 +1,58 @@ +From b71021b203b3793efa709a52b9528a7e8725c1ac Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Wed, 20 May 2026 23:29:25 +0000 +Subject: [PATCH 04/12] [dhcp-relay] Fix stack buffer overflow in hh buffer in + send_packet + +In send_packet implementations for LPF (common/lpf.c) and NIT (common/nit.c), +the hardware header is assembled into a local stack buffer 'hh' of size 128 bytes. +If the assembled hardware header length 'hbufp' exceeded the size of 'hh', +it would overflow the stack buffer. + +This CL adds explicit bounds checks 'hbufp > sizeof(hh)' after calling +assemble_hw_header to prevent stack buffer overflows, matching the safe +implementation already present in dlpi.c. + +BUG=510453473 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + common/lpf.c | 5 +++++ + common/nit.c | 5 +++++ + 2 files changed, 10 insertions(+) + +diff --git a/common/lpf.c b/common/lpf.c +index 9be86afb..042dcba7 100644 +--- a/common/lpf.c ++++ b/common/lpf.c +@@ -355,6 +355,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) + + /* Assemble the headers... */ + assemble_hw_header (interface, (unsigned char *)hh, &hbufp, hto); ++ if (hbufp > sizeof(hh)) { ++ log_error("send_packet: hh buffer too small (%d > %d)", ++ hbufp, (int)sizeof(hh)); ++ return -1; ++ } + fudge = hbufp % 4; /* IP header must be word-aligned. */ + + if (hbufp + fudge + 28 + len > sizeof(ih)) { +diff --git a/common/nit.c b/common/nit.c +index 42b6c33e..c8f62f22 100644 +--- a/common/nit.c ++++ b/common/nit.c +@@ -307,6 +307,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto) + + /* Assemble the headers... */ + assemble_hw_header (interface, (unsigned char *)junk, &hbufp, hto); ++ if (hbufp > sizeof(hh)) { ++ log_error("send_packet: hh buffer too small (%d > %d)", ++ hbufp, (int)sizeof(hh)); ++ return -1; ++ } + + if (28 + len > sizeof(ih)) { + log_error("send_packet: packet too large (%d > %d)", +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0005-dhcp-relay-Fix-stack-buffer-overflow-and-integer-und.patch b/recipes-connectivity/dhcp/dhcp-relay/0005-dhcp-relay-Fix-stack-buffer-overflow-and-integer-und.patch new file mode 100644 index 0000000..ff8d9c2 --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0005-dhcp-relay-Fix-stack-buffer-overflow-and-integer-und.patch
@@ -0,0 +1,48 @@ +From 37d307c52612504381f51dcbce440c431eaa225c Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Wed, 20 May 2026 23:32:59 +0000 +Subject: [PATCH 05/12] [dhcp-relay] Fix stack buffer overflow and integer + underflow in concat_dclists + +In concat_dclists (common/tree.c), two compressed domain lists (list1 and list2) +are uncompressed into a local stack buffer 'uncompbuf' of size 32 * NS_MAXCDNAME. + +A vulnerability existed where, if the first list uncompressed to exactly fill +the buffer (uncomp_len == sizeof(uncompbuf)), the code would still attempt to +append a comma separator: +1. Writing the comma byte out of bounds (1-byte stack buffer overflow). +2. Incrementing uncomp_len to sizeof(uncompbuf) + 1. +3. Underflowing the remaining space calculation: (sizeof(uncompbuf) - uncomp_len) + which wrapped to a huge positive value when passed as 'size_t dst_size' + to the second uncompress call, potentially causing a larger stack overflow. + +This CL fixes the vulnerability by adding an explicit bounds check: +'uncomp_len >= sizeof(uncompbuf) - 1' before attempting to append the comma. +If there is no space for the comma and at least a portion of the second list, +it logs an error and returns 0. + +BUG=510454983 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + common/tree.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/common/tree.c b/common/tree.c +index 68173354..5cf635c3 100644 +--- a/common/tree.c ++++ b/common/tree.c +@@ -4204,6 +4204,10 @@ int concat_dclists (struct data_string* result, + if (list2 && (list2->data) && (list2->len)) { + /* If first list wasn't empty, add a comma */ + if (uncomp_len > 0) { ++ if (uncomp_len >= sizeof(uncompbuf) - 1) { ++ log_error("concat_dclists: no space for comma"); ++ return (0); ++ } + *uncomp++ = ','; + uncomp_len++; + } +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0006-dhcp-relay-Fix-out-of-bounds-read-in-MRns_name_compr.patch b/recipes-connectivity/dhcp/dhcp-relay/0006-dhcp-relay-Fix-out-of-bounds-read-in-MRns_name_compr.patch new file mode 100644 index 0000000..3da5ee7 --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0006-dhcp-relay-Fix-out-of-bounds-read-in-MRns_name_compr.patch
@@ -0,0 +1,56 @@ +From 283f1c1bd2866208b62ddfc6790797b55871a075 Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Thu, 21 May 2026 00:25:43 +0000 +Subject: [PATCH 06/12] [dhcp-relay] Fix out-of-bounds read in + MRns_name_compress_list + +In MRns_name_compress_list (common/ns_name.c), the function parsed a +comma-separated list of domain names using strchr and strlen. However, these +standard string functions are unbounded and assume null-termination. + +If the input buffer 'buf' was not null-terminated within the specified 'buflen' +(or contained garbage due to previous uninitialized memory leaks or overflows), +strchr and strlen could read past the end of the buffer. If a comma was found +beyond 'buflen', it could result in an out-of-bounds read during memcpy. + +This CL fixes the vulnerability by: +1. Ensuring we stop parsing at the first null terminator if one exists within + 'buflen' by shrinking 'src_end' to the null terminator. +2. Replacing the unbounded strchr and strlen calls inside the parsing loop + with bounded memchr calls limited to the remaining buffer size (src_end - src). + +This ensures we never read beyond the allocated buffer size or the null terminator. + +BUG=510454798 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + common/ns_name.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/common/ns_name.c b/common/ns_name.c +index f51f5411..039bcef2 100644 +--- a/common/ns_name.c ++++ b/common/ns_name.c +@@ -794,9 +794,16 @@ int MRns_name_compress_list(const char* buf, int buflen, + + src = buf; + src_end = buf + buflen; ++ ++ /* If there is a null terminator within buflen, treat it as the end */ ++ const char *null_term = memchr(buf, '\0', buflen); ++ if (null_term != NULL) { ++ src_end = null_term; ++ } ++ + while (src < src_end) { +- char *comma = strchr(src, ','); +- int copylen = ((comma != NULL) ? comma - src : strlen(src)); ++ const char *comma = memchr(src, ',', src_end - src); ++ int copylen = ((comma != NULL) ? comma - src : src_end - src); + if (copylen > (sizeof(cur_name) - 1)) { + errno = EMSGSIZE; + return (-1); +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0007-dhcp-relay-Fix-heap-buffer-underflow-in-parse_numeri.patch b/recipes-connectivity/dhcp/dhcp-relay/0007-dhcp-relay-Fix-heap-buffer-underflow-in-parse_numeri.patch new file mode 100644 index 0000000..9731331 --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0007-dhcp-relay-Fix-heap-buffer-underflow-in-parse_numeri.patch
@@ -0,0 +1,50 @@ +From 009670c4949555bc835e7313a732f0cafff0f658 Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Thu, 21 May 2026 00:28:55 +0000 +Subject: [PATCH 07/12] [dhcp-relay] Fix heap buffer underflow in + parse_numeric_aggregate + +In parse_numeric_aggregate (common/parse.c), when parsing a numeric list +without a predefined size (buf is NULL and *max is 0 initially), the code +first parses all elements into a linked list 'c' and then allocates a +heap buffer 'bufp' of size 'count * size / 8' to copy them in reverse order. + +However, the start pointer 's' for the backward conversion loop was +incorrectly calculated as: + s = bufp + count - size / 8; + +This assumes that 'size / 8' is always 1 (i.e. 8-bit numbers). If 'size' +is larger than 8 (e.g. 16-bit or 32-bit integers), 's' was set to an +incorrect offset, causing the backward copy loop to write bytes before +the start of 'bufp', resulting in a Heap Buffer Underflow. + +This CL fixes the issue by correcting the start pointer calculation to: + s = bufp + (count - 1) * (size / 8); + +This correctly scales the starting offset by the element size, ensuring +all writes stay within the allocated heap buffer boundaries regardless of +the integer precision. + +BUG=510454409 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + common/parse.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/common/parse.c b/common/parse.c +index b123a6c7..4daac286 100644 +--- a/common/parse.c ++++ b/common/parse.c +@@ -787,7 +787,7 @@ unsigned char *parse_numeric_aggregate (cfile, buf, + bufp = (unsigned char *)dmalloc (count * size / 8, MDL); + if (!bufp) + log_fatal ("no space for numeric aggregate."); +- s = bufp + count - size / 8; ++ s = bufp + (count - 1) * (size / 8); + *max = count; + } + while (c) { +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0008-dhcp-relay-Fix-integer-wrap-around-logic-flaw-in-con.patch b/recipes-connectivity/dhcp/dhcp-relay/0008-dhcp-relay-Fix-integer-wrap-around-logic-flaw-in-con.patch new file mode 100644 index 0000000..154311b --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0008-dhcp-relay-Fix-integer-wrap-around-logic-flaw-in-con.patch
@@ -0,0 +1,52 @@ +From 0eceb2b0053beaee207218d6d4c45c58b6d53705 Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Thu, 21 May 2026 00:32:45 +0000 +Subject: [PATCH 08/12] [dhcp-relay] Fix integer wrap-around logic flaw in + converted_length + +In converted_length (omapip/convert.c), the loop used to determine the character +length of an integer in a given base relied on: + newcolumn = column * base; + ... + while (newcolumn > column); + +to detect unsigned 32-bit integer overflow. However, for certain values (e.g. +large numbers in base 10), the wrapped value (column * base) % 2^32 can still +be larger than the previous 'column' value. This caused the loop to continue +unexpectedly, inflating the calculated length ('power'). + +This inflated length subsequently caused binary_to_ascii to emit over-long +strings (with unexpected leading '0's) and potentially led to incorrect buffer +size calculations in callers. + +This CL fixes the issue by implementing a reliable division-based overflow +check: + if (newcolumn / base != column) + return power; + +This safely terminates the loop immediately when the column boundary exceeds +the 32-bit unsigned integer limit, returning the correct length. + +BUG=510454340 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + omapip/convert.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/omapip/convert.c b/omapip/convert.c +index de6c7c86..9b264262 100644 +--- a/omapip/convert.c ++++ b/omapip/convert.c +@@ -141,6 +141,8 @@ int converted_length (buf, base, width) + return power; + power++; + newcolumn = column * base; ++ if (newcolumn / base != column) ++ return power; + /* If we wrap around, it must be the next power of two up. */ + } while (newcolumn > column); + +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0009-dhcp-relay-Fix-NULL-pointer-dereferences-in-hash-tab.patch b/recipes-connectivity/dhcp/dhcp-relay/0009-dhcp-relay-Fix-NULL-pointer-dereferences-in-hash-tab.patch new file mode 100644 index 0000000..c3af5cb --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0009-dhcp-relay-Fix-NULL-pointer-dereferences-in-hash-tab.patch
@@ -0,0 +1,63 @@ +From e752163508eaa3fddc63288e4f68fade5dbb1ad2 Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Thu, 21 May 2026 00:57:25 +0000 +Subject: [PATCH 09/12] [dhcp-relay] Fix NULL pointer dereferences in hash + table operations + +In omapip/hash.c, functions performing hash table operations (add_hash, +delete_hash_entry, and hash_lookup) did not validate whether the provided +'key' pointer was non-NULL before invoking the hash function or string +comparison functions (like strcmp): + hashno = (*table->do_hash)(key, len, ...); + ... + strcmp((const char *)bp->name, key); + +If a NULL key was passed (or stored in a bucket), this led to immediate +NULL pointer dereferences and program crashes. + +This CL fixes the vulnerability by adding explicit NULL checks: +'if (!key)' at the entry points of add_hash, delete_hash_entry, and +hash_lookup, returning early (or returning 0 for lookup) safely without +performing any operations on NULL pointers. + +BUG=510454261 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + omapip/hash.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/omapip/hash.c b/omapip/hash.c +index fccfb1cd..afc48cac 100644 +--- a/omapip/hash.c ++++ b/omapip/hash.c +@@ -405,7 +405,7 @@ void add_hash (table, key, len, pointer, file, line) + struct hash_bucket *bp; + void *foo; + +- if (!table) ++ if (!table || !key) + return; + + if (!len) +@@ -440,7 +440,7 @@ void delete_hash_entry (table, key, len, file, line) + struct hash_bucket *bp, *pbp = (struct hash_bucket *)0; + void *foo; + +- if (!table) ++ if (!table || !key) + return; + + if (!len) +@@ -482,7 +482,7 @@ int hash_lookup (vp, table, key, len, file, line) + int hashno; + struct hash_bucket *bp; + +- if (!table) ++ if (!table || !key) + return 0; + if (!len) + len = find_length(key, table->do_hash); +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0010-dhcp-relay-Fix-Null-Pointer-Dereference-in-omapi_aut.patch b/recipes-connectivity/dhcp/dhcp-relay/0010-dhcp-relay-Fix-Null-Pointer-Dereference-in-omapi_aut.patch new file mode 100644 index 0000000..86fb7eb --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0010-dhcp-relay-Fix-Null-Pointer-Dereference-in-omapi_aut.patch
@@ -0,0 +1,44 @@ +From 07e24f2a0139146c82dab5c03d3ede3248cd65de Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Thu, 21 May 2026 01:04:52 +0000 +Subject: [PATCH 10/12] [dhcp-relay] Fix Null Pointer Dereference in + omapi_auth_key_destroy + +In omapi_auth_key_destroy (omapip/auth.c), the function attempted to +delete the key from the hash table using: + omapi_auth_key_hash_delete(auth_key_hash, a->name, 0, MDL); + +If 'a->name' was NULL, this led to a NULL pointer dereference down the +line in strcmp during hash deletion. + +This CL fixes the issue by checking if 'a->name' is not NULL before +attempting to delete it from the hash table: + if (auth_key_hash != NULL && a->name != NULL) + omapi_auth_key_hash_delete(auth_key_hash, a->name, 0, MDL); + +This prevents any NULL pointer dereference crashes during auth key +destruction when the key name has not been initialized. + +BUG=510453307 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + omapip/auth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/omapip/auth.c b/omapip/auth.c +index a2835a44..5760347a 100644 +--- a/omapip/auth.c ++++ b/omapip/auth.c +@@ -55,7 +55,7 @@ isc_result_t omapi_auth_key_destroy (omapi_object_t *h, + return DHCP_R_INVALIDARG; + a = (omapi_auth_key_t *)h; + +- if (auth_key_hash != NULL) ++ if (auth_key_hash != NULL && a->name != NULL) + omapi_auth_key_hash_delete(auth_key_hash, a->name, 0, MDL); + + if (a->name != NULL) +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0011-dhcp-relay-Fix-out-of-bounds-read-in-delete_hash_ent.patch b/recipes-connectivity/dhcp/dhcp-relay/0011-dhcp-relay-Fix-out-of-bounds-read-in-delete_hash_ent.patch new file mode 100644 index 0000000..177cded --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0011-dhcp-relay-Fix-out-of-bounds-read-in-delete_hash_ent.patch
@@ -0,0 +1,52 @@ +From 86704ceda54f94cb5b09853ede64e700b14b8362 Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Thu, 21 May 2026 01:12:24 +0000 +Subject: [PATCH 11/12] [dhcp-relay] Fix out-of-bounds read in + delete_hash_entry via non-string keys + +In delete_hash_entry (omapip/hash.c), when traversing buckets to delete +an entry, the code used strcmp to compare keys if the stored bucket +indicated a zero-length key (bp->len == 0): + if ((!bp->len && !strcmp((const char *)bp->name, key)) || ... + +However, 'bp->len' can be 0 for non-string binary keys (such as client +identifiers hashed using do_id_hash, where find_length returns 0). +If 'delete_hash_entry' was called to delete a non-null-terminated binary +key, strcmp would read past the end of 'key' (and potentially 'bp->name'), +resulting in an Out-of-Bounds Read. + +This CL fixes the vulnerability by restricting the strcmp comparison +exclusively to string-based hash tables (do_case_hash or do_string_hash), +ensuring we never call strcmp on potentially non-null-terminated binary +keys: + if ((!bp->len && + (table->do_hash == do_case_hash || + table->do_hash == do_string_hash) && + !strcmp((const char *)bp->name, key)) || ... + +Binary keys with len=0 will safely fall through to the second comparison +block using the safe table->cmp (memcmp). + +BUG=510454125 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + omapip/hash.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/omapip/hash.c b/omapip/hash.c +index afc48cac..d4c25000 100644 +--- a/omapip/hash.c ++++ b/omapip/hash.c +@@ -452,6 +452,8 @@ void delete_hash_entry (table, key, len, file, line) + if we find it, delete it. */ + for (bp = table -> buckets [hashno]; bp; bp = bp -> next) { + if ((!bp -> len && ++ (table->do_hash == do_case_hash || ++ table->do_hash == do_string_hash) && + !strcmp ((const char *)bp->name, key)) || + (bp -> len == len && + !(table -> cmp)(bp->name, key, len))) { +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay/0012-dhcp-relay-Fix-off-by-one-buffer-overflow-in-MRns_na.patch b/recipes-connectivity/dhcp/dhcp-relay/0012-dhcp-relay-Fix-off-by-one-buffer-overflow-in-MRns_na.patch new file mode 100644 index 0000000..f0aaa43 --- /dev/null +++ b/recipes-connectivity/dhcp/dhcp-relay/0012-dhcp-relay-Fix-off-by-one-buffer-overflow-in-MRns_na.patch
@@ -0,0 +1,54 @@ +From 4c21648ed5a2168dc13148298bc35bc05e59272d Mon Sep 17 00:00:00 2001 +From: Chris Rauer <crauer@google.com> +Date: Thu, 21 May 2026 01:21:57 +0000 +Subject: [PATCH 12/12] [dhcp-relay] Fix off-by-one buffer overflow in + MRns_name_uncompress_list + +In MRns_name_uncompress_list (common/ns_name.c), domain lists are uncompressed +and concatenated with a comma separator. + +An off-by-one vulnerability existed when appending the comma separator. +If 'dst_remaining' was exactly 1 (1 byte left in the output buffer), the +pre-check 'dst_remaining <= 0' passed, and the code executed: + *dst++ = ','; + *dst = '\0'; + dst_remaining--; + +This wrote the ',' at the last valid byte of the buffer, but advanced the 'dst' +pointer one byte past the allocated buffer boundary and wrote the null +terminator '\0' out of bounds on the heap/stack (Off-by-One Buffer Overflow). + +This CL fixes the issue by adding an explicit check before appending the comma: + if (dst_remaining < 2) { + errno = EMSGSIZE; + return (-1); + } + +This ensures we have at least 2 bytes available (one for the comma, one for +the null terminator) before writing them, preventing any out-of-bounds writes. + +BUG=510454046 +TAG=agy +CONV=9ea40568-b7ac-4352-a0c8-61185ee29a27 +--- + common/ns_name.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/common/ns_name.c b/common/ns_name.c +index 039bcef2..283c4b43 100644 +--- a/common/ns_name.c ++++ b/common/ns_name.c +@@ -732,6 +732,10 @@ int MRns_name_uncompress_list(const unsigned char* buf, int buflen, + } + + if (!first_pass) { ++ if (dst_remaining < 2) { ++ errno = EMSGSIZE; ++ return (-1); ++ } + *dst++ = ','; + *dst = '\0'; + dst_remaining--; +-- +2.54.0.669.g59709faab0-goog +
diff --git a/recipes-connectivity/dhcp/dhcp-relay_%.bbappend b/recipes-connectivity/dhcp/dhcp-relay_%.bbappend index e577b45..08c186e 100644 --- a/recipes-connectivity/dhcp/dhcp-relay_%.bbappend +++ b/recipes-connectivity/dhcp/dhcp-relay_%.bbappend
@@ -1,2 +1,16 @@ FILESEXTRAPATHS:prepend:gbmc := "${THISDIR}/${PN}:" -SRC_URI:append:gbmc = " file://0001-dhcrelay-Remove-forwarding-on-uknown-interfaces.patch" +SRC_URI:append:gbmc = " \ + file://0001-dhcrelay-Remove-forwarding-on-uknown-interfaces.patch \ + file://0001-dhcp-relay-Improve-PRNG-seeding-in-dhcp_context_crea.patch \ + file://0002-dhcp-relay-Fix-stack-buffer-overflow-in-send_packet.patch \ + file://0003-dhcp-relay-Fix-uninitialized-memory-leak-in-add_rela.patch \ + file://0004-dhcp-relay-Fix-stack-buffer-overflow-in-hh-buffer-in.patch \ + file://0005-dhcp-relay-Fix-stack-buffer-overflow-and-integer-und.patch \ + file://0006-dhcp-relay-Fix-out-of-bounds-read-in-MRns_name_compr.patch \ + file://0007-dhcp-relay-Fix-heap-buffer-underflow-in-parse_numeri.patch \ + file://0008-dhcp-relay-Fix-integer-wrap-around-logic-flaw-in-con.patch \ + file://0009-dhcp-relay-Fix-NULL-pointer-dereferences-in-hash-tab.patch \ + file://0010-dhcp-relay-Fix-Null-Pointer-Dereference-in-omapi_aut.patch \ + file://0011-dhcp-relay-Fix-out-of-bounds-read-in-delete_hash_ent.patch \ + file://0012-dhcp-relay-Fix-off-by-one-buffer-overflow-in-MRns_na.patch \ +"