From 371defc35753d04fa8b769b8c859630c3a76e9ed Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Mon, 12 Feb 2024 14:54:36 +1100 Subject: [PATCH] Address CID 486326: Memory - corruptions (OVERRUN) Coverity detected that address->type.sa was too small when copying a struct sockaddr_sin6, use the alterative union element address->type.sin6 instead. --- lib/dns/resconf.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/lib/dns/resconf.c b/lib/dns/resconf.c index d57e0a9fa5..58adf6b84a 100644 --- a/lib/dns/resconf.c +++ b/lib/dns/resconf.c @@ -226,26 +226,35 @@ add_server(isc_mem_t *mctx, const char *address_str, return (ISC_R_BADADDRESSFORM); } - /* XXX: special case: treat all-0 IPv4 address as loopback */ - if (res->ai_family == AF_INET) { - struct in_addr *v4; - unsigned char zeroaddress[] = { 0, 0, 0, 0 }; - unsigned char loopaddress[] = { 127, 0, 0, 1 }; - - v4 = &((struct sockaddr_in *)res->ai_addr)->sin_addr; - if (memcmp(v4, zeroaddress, 4) == 0) { - memmove(v4, loopaddress, 4); - } - } - address = isc_mem_get(mctx, sizeof(*address)); if (res->ai_addrlen > sizeof(address->type)) { isc_mem_put(mctx, address, sizeof(*address)); result = ISC_R_RANGE; goto cleanup; } + + if (res->ai_family == AF_INET) { + struct in_addr *v4; + unsigned char zeroaddress[] = { 0, 0, 0, 0 }; + unsigned char loopaddress[] = { 127, 0, 0, 1 }; + + /* XXX: special case: treat all-0 IPv4 address as loopback */ + v4 = &((struct sockaddr_in *)res->ai_addr)->sin_addr; + if (memcmp(v4, zeroaddress, 4) == 0) { + memmove(v4, loopaddress, 4); + } + memmove(&address->type.sin, res->ai_addr, res->ai_addrlen); + } else if (res->ai_family == AF_INET6) { + memmove(&address->type.sin6, res->ai_addr, res->ai_addrlen); + } else { + isc_mem_put(mctx, address, sizeof(*address)); + UNEXPECTED_ERROR("ai_family (%d) not INET nor INET6", + res->ai_family); + result = ISC_R_UNEXPECTED; + goto cleanup; + } address->length = (unsigned int)res->ai_addrlen; - memmove(&address->type.sa, res->ai_addr, res->ai_addrlen); + ISC_LINK_INIT(address, link); ISC_LIST_APPEND(*nameservers, address, link);