diff --git a/SOURCES/0005-avoid-read-heap-buffer-overflow-332.patch b/SOURCES/0005-avoid-read-heap-buffer-overflow-332.patch new file mode 100644 index 0000000..36d399f --- /dev/null +++ b/SOURCES/0005-avoid-read-heap-buffer-overflow-332.patch @@ -0,0 +1,30 @@ +From 65f83b8bf15a128524ef5fe26e1f1e219ee9b872 Mon Sep 17 00:00:00 2001 +From: Alexey Tikhonov +Date: Fri, 1 Sep 2023 20:00:12 +0200 +Subject: [PATCH] avoid read-heap-buffer-overflow (#332) + +Fix invalid read in ares_parse_soa_reply.c found during fuzzing + +Fixes Bug: #333 +Fix By: lutianxiong (@ltx2018) +--- + ares_parse_soa_reply.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/ares_parse_soa_reply.c b/ares_parse_soa_reply.c +index 35af0a7..5924bbc 100644 +--- a/ares_parse_soa_reply.c ++++ b/ares_parse_soa_reply.c +@@ -65,6 +65,9 @@ ares_parse_soa_reply(const unsigned char *abuf, int alen, + status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len); + if (status != ARES_SUCCESS) + goto failed_stat; ++ ++ if (alen <= len + HFIXEDSZ + 1) ++ goto failed; + aptr += len; + + /* skip qtype & qclass */ +-- +2.38.1 + diff --git a/SOURCES/0006-Merge-pull-request-from-GHSA-x6mf-cxr9-8q6v.patch b/SOURCES/0006-Merge-pull-request-from-GHSA-x6mf-cxr9-8q6v.patch new file mode 100644 index 0000000..3877b9e --- /dev/null +++ b/SOURCES/0006-Merge-pull-request-from-GHSA-x6mf-cxr9-8q6v.patch @@ -0,0 +1,294 @@ +From f22cc01039b6473b736d3bf438f56a2654cdf2b2 Mon Sep 17 00:00:00 2001 +From: Brad House +Date: Mon, 22 May 2023 06:51:34 -0400 +Subject: [PATCH] Merge pull request from GHSA-x6mf-cxr9-8q6v + +* Merged latest OpenBSD changes for inet_net_pton_ipv6() into c-ares. +* Always use our own IP conversion functions now, do not delegate to OS + so we can have consistency in testing and fuzzing. + +Fix By: Brad House (@bradh352) +--- + inet_net_pton.c | 155 ++++++++++++++++++++----------------- + +diff --git a/inet_net_pton.c b/inet_net_pton.c +index 840de50..fc50425 100644 +--- a/inet_net_pton.c ++++ b/inet_net_pton.c +@@ -1,19 +1,20 @@ + + /* +- * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") ++ * Copyright (c) 2012 by Gilles Chehade + * Copyright (c) 1996,1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * +- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES +- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR +- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS ++ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE ++ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL ++ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ++ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ++ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ++ * SOFTWARE. + */ + + #include "ares_setup.h" +@@ -35,9 +36,6 @@ + + const struct ares_in6_addr ares_in6addr_any = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }; + +- +-#ifndef HAVE_INET_NET_PTON +- + /* + * static int + * inet_net_pton_ipv4(src, dst, size) +@@ -60,7 +58,7 @@ const struct ares_in6_addr ares_in6addr_any = { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0, + * Paul Vixie (ISC), June 1996 + */ + static int +-inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) ++ares_inet_net_pton_ipv4(const char *src, unsigned char *dst, size_t size) + { + static const char xdigits[] = "0123456789abcdef"; + static const char digits[] = "0123456789"; +@@ -261,19 +259,14 @@ getv4(const char *src, unsigned char *dst, int *bitsp) + } + + static int +-inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size) ++ares_inet_pton6(const char *src, unsigned char *dst) + { + static const char xdigits_l[] = "0123456789abcdef", +- xdigits_u[] = "0123456789ABCDEF"; ++ xdigits_u[] = "0123456789ABCDEF"; + unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; +- int ch, saw_xdigit; ++ int ch, saw_xdigit, count_xdigit; + unsigned int val; +- int digits; +- int bits; +- size_t bytes; +- int words; +- int ipv4; + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; +@@ -283,22 +276,22 @@ inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size) + if (*++src != ':') + goto enoent; + curtok = src; +- saw_xdigit = 0; ++ saw_xdigit = count_xdigit = 0; + val = 0; +- digits = 0; +- bits = -1; +- ipv4 = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { ++ if (count_xdigit >= 4) ++ goto enoent; + val <<= 4; +- val |= aresx_sztoui(pch - xdigits); +- if (++digits > 4) ++ val |= (pch - xdigits); ++ if (val > 0xffff) + goto enoent; + saw_xdigit = 1; ++ count_xdigit++; + continue; + } + if (ch == ':') { +@@ -308,78 +301,107 @@ inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size) + goto enoent; + colonp = tp; + continue; +- } else if (*src == '\0') ++ } else if (*src == '\0') { + goto enoent; ++ } + if (tp + NS_INT16SZ > endp) +- return (0); +- *tp++ = (unsigned char)((val >> 8) & 0xff); +- *tp++ = (unsigned char)(val & 0xff); ++ goto enoent; ++ *tp++ = (unsigned char) (val >> 8) & 0xff; ++ *tp++ = (unsigned char) val & 0xff; + saw_xdigit = 0; +- digits = 0; ++ count_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && +- getv4(curtok, tp, &bits) > 0) { +- tp += NS_INADDRSZ; ++ ares_inet_net_pton_ipv4(curtok, tp, INADDRSZ) > 0) { ++ tp += INADDRSZ; + saw_xdigit = 0; +- ipv4 = 1; ++ count_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } +- if (ch == '/' && getbits(src, &bits) > 0) +- break; + goto enoent; + } + if (saw_xdigit) { + if (tp + NS_INT16SZ > endp) + goto enoent; +- *tp++ = (unsigned char)((val >> 8) & 0xff); +- *tp++ = (unsigned char)(val & 0xff); ++ *tp++ = (unsigned char) (val >> 8) & 0xff; ++ *tp++ = (unsigned char) val & 0xff; + } +- if (bits == -1) +- bits = 128; +- +- words = (bits + 15) / 16; +- if (words < 2) +- words = 2; +- if (ipv4) +- words = 8; +- endp = tmp + 2 * words; +- + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ +- const ares_ssize_t n = tp - colonp; +- ares_ssize_t i; ++ const int n = tp - colonp; ++ int i; + + if (tp == endp) + goto enoent; + for (i = 1; i <= n; i++) { +- *(endp - i) = *(colonp + n - i); +- *(colonp + n - i) = 0; ++ endp[- i] = colonp[n - i]; ++ colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + goto enoent; + +- bytes = (bits + 7) / 8; +- if (bytes > size) +- goto emsgsize; +- memcpy(dst, tmp, bytes); +- return (bits); ++ memcpy(dst, tmp, NS_IN6ADDRSZ); ++ return (1); + +- enoent: ++enoent: + SET_ERRNO(ENOENT); + return (-1); + +- emsgsize: ++emsgsize: + SET_ERRNO(EMSGSIZE); + return (-1); + } + ++static int ++ares_inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size) ++{ ++ struct ares_in6_addr in6; ++ int ret; ++ int bits; ++ size_t bytes; ++ char buf[INET6_ADDRSTRLEN + sizeof("/128")]; ++ char *sep; ++ const char *errstr; ++ ++ if (strlen(src) >= sizeof buf) { ++ SET_ERRNO(EMSGSIZE); ++ return (-1); ++ } ++ strncpy(buf, src, sizeof buf); ++ ++ sep = strchr(buf, '/'); ++ if (sep != NULL) ++ *sep++ = '\0'; ++ ++ ret = ares_inet_pton6(buf, (unsigned char *)&in6); ++ if (ret != 1) ++ return (-1); ++ ++ if (sep == NULL) ++ bits = 128; ++ else { ++ if (!getbits(sep, &bits)) { ++ SET_ERRNO(ENOENT); ++ return (-1); ++ } ++ } ++ ++ bytes = (bits + 7) / 8; ++ if (bytes > size) { ++ SET_ERRNO(EMSGSIZE); ++ return (-1); ++ } ++ memcpy(dst, &in6, bytes); ++ return (bits); ++} ++ + /* + * int + * inet_net_pton(af, src, dst, size) +@@ -403,18 +425,15 @@ ares_inet_net_pton(int af, const char *src, void *dst, size_t size) + { + switch (af) { + case AF_INET: +- return (inet_net_pton_ipv4(src, dst, size)); ++ return (ares_inet_net_pton_ipv4(src, dst, size)); + case AF_INET6: +- return (inet_net_pton_ipv6(src, dst, size)); ++ return (ares_inet_net_pton_ipv6(src, dst, size)); + default: + SET_ERRNO(EAFNOSUPPORT); + return (-1); + } + } + +-#endif /* HAVE_INET_NET_PTON */ +- +-#ifndef HAVE_INET_PTON + int ares_inet_pton(int af, const char *src, void *dst) + { + int result; +@@ -434,11 +453,3 @@ int ares_inet_pton(int af, const char *src, void *dst) + return 0; + return (result > -1 ? 1 : -1); + } +-#else /* HAVE_INET_PTON */ +-int ares_inet_pton(int af, const char *src, void *dst) +-{ +- /* just relay this to the underlying function */ +- return inet_pton(af, src, dst); +-} +- +-#endif +-- +2.41.0 + diff --git a/SPECS/c-ares.spec b/SPECS/c-ares.spec index 080773b..4246a50 100644 --- a/SPECS/c-ares.spec +++ b/SPECS/c-ares.spec @@ -1,7 +1,7 @@ Summary: A library that performs asynchronous DNS operations Name: c-ares Version: 1.13.0 -Release: 8%{?dist} +Release: 10%{?dist} License: MIT Group: System Environment/Libraries URL: http://c-ares.haxx.se/ @@ -12,6 +12,8 @@ Patch0: 0001-Use-RPM-compiler-options.patch Patch1: 0002-fix-CVE-2021-3672.patch Patch2: 0003-Add-str-len-check-in-config_sortlist-to-avoid-stack-.patch Patch3: 0004-Merge-pull-request-from-GHSA-9g78-jv2r-p7vc.patch +Patch4: 0005-avoid-read-heap-buffer-overflow-332.patch +Patch5: 0006-Merge-pull-request-from-GHSA-x6mf-cxr9-8q6v.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -40,6 +42,8 @@ compile applications or shared objects that use c-ares. %patch1 -p1 -b .dns %patch2 -p1 -b .sortlist %patch3 -p1 -b .udp +%patch4 -p1 -b .buffer +%patch5 -p1 -b .underwrite cp %{SOURCE1} . f=CHANGES ; iconv -f iso-8859-1 -t utf-8 $f -o $f.utf8 ; mv $f.utf8 $f @@ -78,6 +82,12 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man3/ares_* %changelog +* Wed Oct 4 2023 Alexey Tikhonov - 1.13.0-10 +- Resolves: RHEL-7853 - Buffer Underwrite in ares_inet_net_pton() [rhel-8] + +* Fri Sep 8 2023 Alexey Tikhonov - 1.13.0-9 +- Resolves: rhbz#2235805 - read-heap-buffer-overflow in ares_parse_soa_reply [rhel-8] + * Mon May 29 2023 Alexey Tikhonov - 1.13.0-8 - Resolves: rhbz#2209517 - CVE-2023-32067 c-ares: 0-byte UDP payload Denial of Service [rhel-8.9.0]