.gear/c-ares.spec | 152 +++++++++++++++++++++ .gear/rules | 3 + .../tags/25c93f411fd83eed45757b1a43dca014fec6aace | 6 + .gear/tags/list | 1 + .gear/upstream/remotes | 3 + CMakeLists.txt | 6 + RELEASE-PROCEDURE.md | 5 +- configure.ac | 1 + include/ares_build.h.cmake | 5 + include/ares_version.h | 6 +- m4/ax_check_user_namespace.m4 | 4 +- m4/ax_check_uts_namespace.m4 | 4 +- m4/cares-compilers.m4 | 19 +-- m4/cares-functions.m4 | 102 ++++++++++++++ src/lib/ares__readaddrinfo.c | 4 - src/lib/ares_config.h.cmake | 3 + src/lib/ares_getaddrinfo.c | 2 +- src/lib/ares_gethostbyaddr.c | 12 +- src/lib/ares_getnameinfo.c | 14 +- src/lib/ares_parse_uri_reply.c | 3 - src/lib/ares_rand.c | 17 ++- src/lib/inet_ntop.c | 4 +- src/lib/setup_once.h | 4 + src/tools/acountry.c | 4 +- test/dns-proto.cc | 14 +- 25 files changed, 343 insertions(+), 55 deletions(-) diff --git a/.gear/c-ares.spec b/.gear/c-ares.spec new file mode 100644 index 0000000..8c96f06 --- /dev/null +++ b/.gear/c-ares.spec @@ -0,0 +1,152 @@ +%define _unpackaged_files_terminate_build 1 + +Name: c-ares +Version: 1.19.1 +Release: alt1 + +Summary: A library that performs asynchronous DNS operations +License: MIT +Group: System/Libraries + +Url: http://c-ares.haxx.se/ +Source: %url/download/c-ares-%version.tar +Patch0: %name-%version-%release.patch + +BuildRequires(pre): rpm-macros-cmake +BuildRequires: cmake +# need for test/configure +BuildRequires: gcc-c++ + +%description +c-ares is a C library that performs DNS requests and name resolves +asynchronously. This package contains little utilities built with +this library. + +%package -n libcares +Summary: A library that performs asynchronous DNS operations +Group: System/Libraries + +%description -n libcares +c-ares is a C library that performs DNS requests and name resolves +asynchronously. c-ares is a fork of the library named 'ares', written +by Greg Hudson at MIT. + +%package -n libcares-devel +Summary: Libraries, includes, etc. to develop applications used c-ares +Group: System/Libraries +Requires: libcares = %version-%release + +%description -n libcares-devel +This package contains the header files and libraries links needed to +compile applications or shared objects that use c-ares. + +%prep +%setup -n c-ares-%version +%patch0 -p1 + +%build +%cmake -DCMAKE_INSTALL_LIBDIR:PATH="%_libdir" -DCARES_BUILD_TESTS:BOOL=ON +%cmake_build + +%install +%cmake_install + +%check +%_cmake__builddir/bin/arestest --gtest_filter=-*.Live* + +%files +%_bindir/* +%_man1dir/* + +%files -n libcares +%_libdir/*.so.* + +%files -n libcares-devel +%_includedir/* +%_libdir/*.so +%_pkgconfigdir/*.pc +%_libdir/cmake/%name +%_man3dir/* + +%changelog +* Wed Jul 05 2023 Alexey Shabalin 1.19.1-alt1 +- 1.19.1 (Fixes: CVE-2023-31124, CVE-2023-31130, CVE-2023-31147, CVE-2023-32067) + +* Mon Apr 10 2023 Alexey Shabalin 1.19.0-alt2 +- switch to build with cmake +- backport patch for fix memory leak in ares_send + +* Sat Feb 04 2023 Anton Farygin 1.19.0-alt1 +- 1.19.0 (Fixes: CVE-2022-4904) + +* Thu Nov 25 2021 Anton Farygin 1.18.1-alt1 +- 1.18.1 +- enabled tests + +* Wed Aug 11 2021 Anton Farygin 1.17.2-alt1 +- 1.17.2 (Fixes: CVE-2021-3672) + +* Tue Jul 27 2021 Anton Farygin 1.17.1-alt2 +- fixed tools install in c-ares package + +* Mon Nov 23 2020 Anton Farygin 1.17.1-alt1 +- 1.17.1 + +* Tue Nov 17 2020 Anton Farygin 1.16.1-alt2 +- added 0d252eb commit from upstream to resolve security issue (fixes: CVE-2020-8277) + +* Fri May 15 2020 Anton Farygin 1.16.1-alt1 +- 1.16.1 + +* Tue Mar 31 2020 Anton Farygin 1.16.0-alt1 +- 1.16.0 + +* Thu Nov 15 2018 Anton Farygin 1.15.0-alt1 +- 1.15.0 + +* Tue May 15 2018 Anton Farygin 1.14.0-alt1 +- 1.14.0 + +* Tue Aug 08 2017 Anton Farygin 1.13.0-alt1 +- 1.13.0 with these security fixes: + * CVE-2016-5180 - Heap-based buffer overflow in the ares_create_query function. + * CVE-2017-1000381 - NAPTR parser out of bounds access. + +* Wed Aug 03 2016 Vitaly Lipatov 1.11.0-alt1 +- new version 1.11.0 (with rpmrb script) + +* Wed Sep 10 2014 Eugeny A. Rostovtsev (REAL) 1.10.0-alt1 +- Version 1.10.0 + +* Tue Dec 27 2011 Victor Forsiuk 1.7.5-alt2 +- Fix RPATH issue. + +* Sat Aug 20 2011 Victor Forsiuk 1.7.5-alt1 +- 1.7.5 + +* Tue Dec 14 2010 Victor Forsiuk 1.7.4-alt1 +- 1.7.4 + +* Fri Nov 26 2010 Victor Forsiuk 1.7.3-alt2 +- Rebuilt for soname set-versions. + +* Mon Aug 09 2010 Victor Forsiuk 1.7.3-alt1 +- 1.7.3 + +* Fri Mar 26 2010 Victor Forsiuk 1.7.1-alt1 +- 1.7.1 + +* Tue Dec 22 2009 Victor Forsyuk 1.7.0-alt1 +- 1.7.0 + +* Thu Dec 11 2008 Victor Forsyuk 1.6.0-alt1 +- 1.6.0 + +* Wed Nov 26 2008 Victor Forsyuk 1.5.3-alt2 +- Removed obsolete %%post* scripts. + +* Fri Sep 12 2008 Victor Forsyuk 1.5.3-alt1 +- 1.5.3 + +* Thu Jun 12 2008 Victor Forsyuk 1.5.2-alt1 +- Initial build. diff --git a/.gear/rules b/.gear/rules new file mode 100644 index 0000000..3f3433b --- /dev/null +++ b/.gear/rules @@ -0,0 +1,3 @@ +tar: v@version@:. +diff: v@version@:. . +spec: .gear/c-ares.spec diff --git a/.gear/tags/25c93f411fd83eed45757b1a43dca014fec6aace b/.gear/tags/25c93f411fd83eed45757b1a43dca014fec6aace new file mode 100644 index 0000000..1972646 --- /dev/null +++ b/.gear/tags/25c93f411fd83eed45757b1a43dca014fec6aace @@ -0,0 +1,6 @@ +object 6360e96b5cf8e5980c887ce58ef727e53d77243a +type commit +tag v1.19.1 +tagger Alexey Shabalin 1688585393 +0300 + +v1.19.1 diff --git a/.gear/tags/list b/.gear/tags/list new file mode 100644 index 0000000..43a047e --- /dev/null +++ b/.gear/tags/list @@ -0,0 +1 @@ +25c93f411fd83eed45757b1a43dca014fec6aace v1.19.1 diff --git a/.gear/upstream/remotes b/.gear/upstream/remotes new file mode 100644 index 0000000..653a961 --- /dev/null +++ b/.gear/upstream/remotes @@ -0,0 +1,3 @@ +[remote "upstream"] + url = https://github.com/c-ares/c-ares.git + fetch = +refs/heads/*:refs/remotes/upstream/* diff --git a/CMakeLists.txt b/CMakeLists.txt index e2290af..0a40388 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,7 @@ CARES_FUNCTION_IN_LIBRARY (clock_gettime rt HAVE_LIBRT) # Look for necessary includes CHECK_INCLUDE_FILES (sys/types.h HAVE_SYS_TYPES_H) +CHECK_INCLUDE_FILES (sys/random.h HAVE_SYS_RANDOM_H) CHECK_INCLUDE_FILES (sys/socket.h HAVE_SYS_SOCKET_H) CHECK_INCLUDE_FILES (sys/sockio.h HAVE_SYS_SOCKIO_H) CHECK_INCLUDE_FILES (arpa/inet.h HAVE_ARPA_INET_H) @@ -281,6 +282,7 @@ CARES_EXTRAINCLUDE_IFSET (HAVE_STDLIB_H stdlib.h) CARES_EXTRAINCLUDE_IFSET (HAVE_STRING_H string.h) CARES_EXTRAINCLUDE_IFSET (HAVE_STRINGS_H strings.h) CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_IOCTL_H sys/ioctl.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_RANDOM_H sys/random.h) CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_SELECT_H sys/select.h) CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_SOCKET_H sys/socket.h) CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_SOCKIO_H sys/sockio.h) @@ -365,6 +367,7 @@ CHECK_SYMBOL_EXISTS (gethostbyaddr "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOST CHECK_SYMBOL_EXISTS (gethostbyname "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTBYNAME) CHECK_SYMBOL_EXISTS (gethostname "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTNAME) CHECK_SYMBOL_EXISTS (getnameinfo "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETNAMEINFO) +CHECK_SYMBOL_EXISTS (getrandom "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETRANDOM) CHECK_SYMBOL_EXISTS (getservbyport_r "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETSERVBYPORT_R) CHECK_SYMBOL_EXISTS (getservbyname_r "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETSERVBYNAME_R) CHECK_SYMBOL_EXISTS (gettimeofday "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETTIMEOFDAY) @@ -562,6 +565,9 @@ ENDIF () IF (HAVE_SYS_TYPES_H) SET (CARES_HAVE_SYS_TYPES_H 1) ENDIF () +IF (HAVE_SYS_RANDOM_H) + SET (CARES_HAVE_SYS_RANDOM_H 1) +ENDIF() IF (HAVE_SYS_SOCKET_H) SET (CARES_HAVE_SYS_SOCKET_H 1) ENDIF() diff --git a/RELEASE-PROCEDURE.md b/RELEASE-PROCEDURE.md index c167707..1abc9a3 100644 --- a/RELEASE-PROCEDURE.md +++ b/RELEASE-PROCEDURE.md @@ -10,6 +10,9 @@ in the source code repo `CARES_LIB_VERSIONINFO` set to the same value to denote the current shared object versioning. +- edit `include/ares_version.h` and set `ARES_VERSION_*` definitions to reflect + the current version. + - make sure all relevant changes are committed on the master branch - tag the git repo in this style: `git tag -a cares-1_14_0` -a annotates the @@ -26,8 +29,6 @@ in the source code repo - upload the resulting files to https://c-ares.org/download/ -- update `ares_version.h` for the next version - in the c-ares-www repo ---------------------- diff --git a/configure.ac b/configure.ac index 54e79d6..2d65eb7 100644 --- a/configure.ac +++ b/configure.ac @@ -666,6 +666,7 @@ CARES_CHECK_FUNC_GETENV CARES_CHECK_FUNC_GETHOSTBYADDR CARES_CHECK_FUNC_GETHOSTBYNAME CARES_CHECK_FUNC_GETHOSTNAME +CARES_CHECK_FUNC_GETRANDOM CARES_CHECK_FUNC_GETSERVBYPORT_R CARES_CHECK_FUNC_INET_NET_PTON CARES_CHECK_FUNC_INET_NTOP diff --git a/include/ares_build.h.cmake b/include/ares_build.h.cmake index e847f17..6bad69a 100644 --- a/include/ares_build.h.cmake +++ b/include/ares_build.h.cmake @@ -8,6 +8,7 @@ * files. We need to include some dependent headers that may be system specific * for C-Ares */ #cmakedefine CARES_HAVE_SYS_TYPES_H +#cmakedefine CARES_HAVE_SYS_RANDOM_H #cmakedefine CARES_HAVE_SYS_SOCKET_H #cmakedefine CARES_HAVE_WINDOWS_H #cmakedefine CARES_HAVE_WS2TCPIP_H @@ -20,6 +21,10 @@ # include #endif +#ifdef CARES_HAVE_SYS_RANDOM_H +# include +#endif + #ifdef CARES_HAVE_SYS_SOCKET_H # include #endif diff --git a/include/ares_version.h b/include/ares_version.h index 4d8d62f..9db836e 100644 --- a/include/ares_version.h +++ b/include/ares_version.h @@ -3,15 +3,15 @@ #define ARES__VERSION_H /* This is the global package copyright */ -#define ARES_COPYRIGHT "2004 - 2021 Daniel Stenberg, ." +#define ARES_COPYRIGHT "2004 - 2023 Daniel Stenberg, ." #define ARES_VERSION_MAJOR 1 #define ARES_VERSION_MINOR 19 -#define ARES_VERSION_PATCH 0 +#define ARES_VERSION_PATCH 1 #define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\ (ARES_VERSION_MINOR<<8)|\ (ARES_VERSION_PATCH)) -#define ARES_VERSION_STR "1.19.0" +#define ARES_VERSION_STR "1.19.1" #if (ARES_VERSION >= 0x010700) # define CARES_HAVE_ARES_LIBRARY_INIT 1 diff --git a/m4/ax_check_user_namespace.m4 b/m4/ax_check_user_namespace.m4 index 27ba698..ede18b9 100644 --- a/m4/ax_check_user_namespace.m4 +++ b/m4/ax_check_user_namespace.m4 @@ -34,9 +34,9 @@ int main() { pid_t child = clone(userfn, userst + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0); if (child < 0) return 1; - sprintf(buffer, "/proc/%d/uid_map", child); + snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child); fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755); - sprintf(buffer, "0 %d 1\n", getuid()); + snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid()); write(fd, buffer, strlen(buffer)); close(fd); diff --git a/m4/ax_check_uts_namespace.m4 b/m4/ax_check_uts_namespace.m4 index cf7b145..94f03d3 100644 --- a/m4/ax_check_uts_namespace.m4 +++ b/m4/ax_check_uts_namespace.m4 @@ -55,9 +55,9 @@ int main() { pid_t child = clone(fn, st + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0); if (child < 0) return 1; - sprintf(buffer, "/proc/%d/uid_map", child); + snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child); fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755); - sprintf(buffer, "0 %d 1\n", getuid()); + snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid()); write(fd, buffer, strlen(buffer)); close(fd); diff --git a/m4/cares-compilers.m4 b/m4/cares-compilers.m4 index a5b1e2b..1f36c30 100644 --- a/m4/cares-compilers.m4 +++ b/m4/cares-compilers.m4 @@ -142,19 +142,12 @@ AC_DEFUN([CARES_CHECK_COMPILER_GNU_C], [ gccvhi=`echo $gccver | cut -d . -f1` gccvlo=`echo $gccver | cut -d . -f2` compiler_num=`(expr $gccvhi "*" 100 + $gccvlo) 2>/dev/null` - flags_dbg_all="-g -g0 -g1 -g2 -g3" - flags_dbg_all="$flags_dbg_all -ggdb" - flags_dbg_all="$flags_dbg_all -gstabs" - flags_dbg_all="$flags_dbg_all -gstabs+" - flags_dbg_all="$flags_dbg_all -gcoff" - flags_dbg_all="$flags_dbg_all -gxcoff" - flags_dbg_all="$flags_dbg_all -gdwarf-2" - flags_dbg_all="$flags_dbg_all -gvms" - flags_dbg_yes="-g" - flags_dbg_off="-g0" - flags_opt_all="-O -O0 -O1 -O2 -O3 -Os" - flags_opt_yes="-O2" - flags_opt_off="-O0" + flags_dbg_all="" + flags_dbg_yes="" + flags_dbg_off="" + flags_opt_all="" + flags_opt_yes="" + flags_opt_off="" CURL_CHECK_DEF([_WIN32], [], [silent]) else AC_MSG_RESULT([no]) diff --git a/m4/cares-functions.m4 b/m4/cares-functions.m4 index d4f4f99..ce8d2f9 100644 --- a/m4/cares-functions.m4 +++ b/m4/cares-functions.m4 @@ -186,6 +186,24 @@ cares_includes_stropts="\ ]) +dnl CARES_INCLUDES_SYS_RANDOM +dnl ------------------------------------------------- +dnl Set up variable with list of headers that must be +dnl included when sys/random.h is to be included. + +AC_DEFUN([CARES_INCLUDES_SYS_RANDOM], [ +cares_includes_sys_random="\ +/* includes start */ +#ifdef HAVE_SYS_RANDOM_H +# include +#endif +/* includes end */" + AC_CHECK_HEADERS( + sys/random.h, + [], [], [$cares_includes_sys_random]) +]) + + dnl CARES_INCLUDES_SYS_SOCKET dnl ------------------------------------------------- dnl Set up variable with list of headers that must be @@ -1520,6 +1538,90 @@ AC_DEFUN([CARES_CHECK_FUNC_GETHOSTNAME], [ fi ]) +dnl CARES_CHECK_FUNC_GETRANDOM +dnl ------------------------------------------------- +dnl Verify if getrandom is available, prototyped, and +dnl can be compiled. If all of these are true, and +dnl usage has not been previously disallowed with +dnl shell variable cares_disallow_getrandom, then +dnl HAVE_GETRANDOM will be defined. + +AC_DEFUN([CARES_CHECK_FUNC_GETRANDOM], [ + AC_REQUIRE([CARES_INCLUDES_SYS_RANDOM])dnl + # + tst_links_getrandom="unknown" + tst_proto_getrandom="unknown" + tst_compi_getrandom="unknown" + tst_allow_getrandom="unknown" + # + AC_MSG_CHECKING([if getrandom can be linked]) + AC_LINK_IFELSE([ + AC_LANG_FUNC_LINK_TRY([getrandom]) + ],[ + AC_MSG_RESULT([yes]) + tst_links_getrandom="yes" + ],[ + AC_MSG_RESULT([no]) + tst_links_getrandom="no" + ]) + # + if test "$tst_links_getrandom" = "yes"; then + AC_MSG_CHECKING([if getrandom is prototyped]) + AC_EGREP_CPP([getrandom],[ + $cares_includes_sys_random + ],[ + AC_MSG_RESULT([yes]) + tst_proto_getrandom="yes" + ],[ + AC_MSG_RESULT([no]) + tst_proto_getrandom="no" + ]) + fi + # + if test "$tst_proto_getrandom" = "yes"; then + AC_MSG_CHECKING([if getrandom is compilable]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $cares_includes_sys_random + ]],[[ + if(0 != getrandom(0, 0, 0)) + return 1; + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_compi_getrandom="yes" + ],[ + AC_MSG_RESULT([no]) + tst_compi_getrandom="no" + ]) + fi + # + if test "$tst_compi_getrandom" = "yes"; then + AC_MSG_CHECKING([if getrandom usage allowed]) + if test "x$cares_disallow_getrandom" != "xyes"; then + AC_MSG_RESULT([yes]) + tst_allow_getrandom="yes" + else + AC_MSG_RESULT([no]) + tst_allow_getrandom="no" + fi + fi + # + AC_MSG_CHECKING([if getrandom might be used]) + if test "$tst_links_getrandom" = "yes" && + test "$tst_proto_getrandom" = "yes" && + test "$tst_compi_getrandom" = "yes" && + test "$tst_allow_getrandom" = "yes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED(HAVE_GETRANDOM, 1, + [Define to 1 if you have the getrandom function.]) + ac_cv_func_getrandom="yes" + else + AC_MSG_RESULT([no]) + ac_cv_func_getrandom="no" + fi +]) + dnl CARES_CHECK_FUNC_GETSERVBYPORT_R dnl ------------------------------------------------- diff --git a/src/lib/ares__readaddrinfo.c b/src/lib/ares__readaddrinfo.c index 2315df9..f0b3dcf 100644 --- a/src/lib/ares__readaddrinfo.c +++ b/src/lib/ares__readaddrinfo.c @@ -197,10 +197,6 @@ int ares__readaddrinfo(FILE *fp, } } - if (status != ARES_SUCCESS) - /* Ignore line if invalid address string for the requested family. */ - continue; - if (want_cname) { for (i = 0; i < alias_count; ++i) diff --git a/src/lib/ares_config.h.cmake b/src/lib/ares_config.h.cmake index 798820a..db0dfe7 100644 --- a/src/lib/ares_config.h.cmake +++ b/src/lib/ares_config.h.cmake @@ -123,6 +123,9 @@ /* Define to 1 if you have the getnameinfo function. */ #cmakedefine HAVE_GETNAMEINFO +/* Define to 1 if you have the getrandom function. */ +#cmakedefine HAVE_GETRANDOM + /* Define to 1 if you have the getservbyport_r function. */ #cmakedefine HAVE_GETSERVBYPORT_R diff --git a/src/lib/ares_getaddrinfo.c b/src/lib/ares_getaddrinfo.c index cb49424..7ba8e91 100644 --- a/src/lib/ares_getaddrinfo.c +++ b/src/lib/ares_getaddrinfo.c @@ -825,7 +825,7 @@ static int as_is_first(const struct host_query* hquery) char* p; int ndots = 0; size_t nname = hquery->name?strlen(hquery->name):0; - for (p = hquery->name; *p; p++) + for (p = hquery->name; p && *p; p++) { if (*p == '.') { diff --git a/src/lib/ares_gethostbyaddr.c b/src/lib/ares_gethostbyaddr.c index c62d230..8714bae 100644 --- a/src/lib/ares_gethostbyaddr.c +++ b/src/lib/ares_gethostbyaddr.c @@ -53,7 +53,7 @@ static void addr_callback(void *arg, int status, int timeouts, static void end_aquery(struct addr_query *aquery, int status, struct hostent *host); static int file_lookup(struct ares_addr *addr, struct hostent **host); -static void ptr_rr_name(char *name, const struct ares_addr *addr); +static void ptr_rr_name(char *name, int name_size, const struct ares_addr *addr); void ares_gethostbyaddr(ares_channel channel, const void *addr, int addrlen, int family, ares_host_callback callback, void *arg) @@ -105,7 +105,7 @@ static void next_lookup(struct addr_query *aquery) switch (*p) { case 'b': - ptr_rr_name(name, &aquery->addr); + ptr_rr_name(name, sizeof(name), &aquery->addr); aquery->remaining_lookups = p + 1; ares_query(aquery->channel, name, C_IN, T_PTR, addr_callback, aquery); @@ -255,7 +255,7 @@ static int file_lookup(struct ares_addr *addr, struct hostent **host) return status; } -static void ptr_rr_name(char *name, const struct ares_addr *addr) +static void ptr_rr_name(char *name, int name_size, const struct ares_addr *addr) { if (addr->family == AF_INET) { @@ -264,20 +264,20 @@ static void ptr_rr_name(char *name, const struct ares_addr *addr) unsigned long a2 = (laddr >> 16UL) & 0xFFUL; unsigned long a3 = (laddr >> 8UL) & 0xFFUL; unsigned long a4 = laddr & 0xFFUL; - sprintf(name, "%lu.%lu.%lu.%lu.in-addr.arpa", a4, a3, a2, a1); + snprintf(name, name_size, "%lu.%lu.%lu.%lu.in-addr.arpa", a4, a3, a2, a1); } else { unsigned char *bytes = (unsigned char *)&addr->addrV6; /* There are too many arguments to do this in one line using * minimally C89-compliant compilers */ - sprintf(name, + snprintf(name, name_size, "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.", bytes[15]&0xf, bytes[15] >> 4, bytes[14]&0xf, bytes[14] >> 4, bytes[13]&0xf, bytes[13] >> 4, bytes[12]&0xf, bytes[12] >> 4, bytes[11]&0xf, bytes[11] >> 4, bytes[10]&0xf, bytes[10] >> 4, bytes[9]&0xf, bytes[9] >> 4, bytes[8]&0xf, bytes[8] >> 4); - sprintf(name+strlen(name), + snprintf(name+strlen(name), name_size-strlen(name), "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.ip6.arpa", bytes[7]&0xf, bytes[7] >> 4, bytes[6]&0xf, bytes[6] >> 4, bytes[5]&0xf, bytes[5] >> 4, bytes[4]&0xf, bytes[4] >> 4, diff --git a/src/lib/ares_getnameinfo.c b/src/lib/ares_getnameinfo.c index 966919a..92f4315 100644 --- a/src/lib/ares_getnameinfo.c +++ b/src/lib/ares_getnameinfo.c @@ -327,7 +327,7 @@ static char *lookup_service(unsigned short port, int flags, else { /* get port as a string */ - sprintf(tmpbuf, "%u", (unsigned int)ntohs(port)); + snprintf(tmpbuf, sizeof(tmpbuf), "%u", (unsigned int)ntohs(port)); name = tmpbuf; } name_len = strlen(name); @@ -364,11 +364,11 @@ static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags, { if (is_scope_long) { - sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id); + snprintf(&tmpbuf[1], sizeof(tmpbuf)-1, "%lu", (unsigned long)addr6->sin6_scope_id); } else { - sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id); + snprintf(&tmpbuf[1], sizeof(tmpbuf)-1, "%u", (unsigned int)addr6->sin6_scope_id); } } else @@ -377,22 +377,22 @@ static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags, { if (is_scope_long) { - sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id); + snprintf(&tmpbuf[1], sizeof(tmpbuf)-1, "%lu", (unsigned long)addr6->sin6_scope_id); } else { - sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id); + snprintf(&tmpbuf[1], sizeof(tmpbuf)-1, "%u", (unsigned int)addr6->sin6_scope_id); } } } #else if (is_scope_long) { - sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id); + snprintf(&tmpbuf[1], sizeof(tmpbuf)-1, "%lu", (unsigned long)addr6->sin6_scope_id); } else { - sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id); + snprintf(&tmpbuf[1], sizeof(tmpbuf)-1, "%u", (unsigned int)addr6->sin6_scope_id); } (void) flags; #endif diff --git a/src/lib/ares_parse_uri_reply.c b/src/lib/ares_parse_uri_reply.c index d79b5c4..bb28267 100644 --- a/src/lib/ares_parse_uri_reply.c +++ b/src/lib/ares_parse_uri_reply.c @@ -151,9 +151,6 @@ ares_parse_uri_reply (const unsigned char *abuf, int alen, uri_curr->uri = strncpy(uri_curr->uri, (const char *)vptr, rr_len-4); uri_curr->uri[rr_len-4]='\0'; uri_curr->ttl = rr_ttl; - - if (status != ARES_SUCCESS) - break; } /* Don't lose memory in the next iteration */ diff --git a/src/lib/ares_rand.c b/src/lib/ares_rand.c index 766c1e6..f07d419 100644 --- a/src/lib/ares_rand.c +++ b/src/lib/ares_rand.c @@ -155,7 +155,7 @@ static int ares__init_rand_engine(ares_rand_state *state) { memset(state, 0, sizeof(*state)); -#if defined(HAVE_ARC4RANDOM_BUF) || defined(_WIN32) +#if defined(HAVE_ARC4RANDOM_BUF) || defined(HAVE_GETRANDOM) || defined(_WIN32) state->type = ARES_RAND_OS; return 1; #elif defined(CARES_RANDOM_FILE) @@ -241,6 +241,21 @@ static void ares__rand_bytes(ares_rand_state *state, unsigned char *buf, size_t #elif defined(HAVE_ARC4RANDOM_BUF) arc4random_buf(buf, len); return; +#elif defined(HAVE_GETRANDOM) + while (1) { + size_t n = len - bytes_read; + /* getrandom() on Linux always succeeds and is never + * interrupted by a signal when requesting <= 256 bytes. + */ + ssize_t rv = getrandom(buf + bytes_read, n > 256 ? 256 : n, 0); + if (rv <= 0) + continue; /* Just retry. */ + + bytes_read += rv; + if (bytes_read == len) + return; + } + break; #else /* Shouldn't be possible to be here */ break; diff --git a/src/lib/inet_ntop.c b/src/lib/inet_ntop.c index 6645c0a..e33dda5 100644 --- a/src/lib/inet_ntop.c +++ b/src/lib/inet_ntop.c @@ -84,7 +84,7 @@ inet_ntop4(const unsigned char *src, char *dst, size_t size) static const char fmt[] = "%u.%u.%u.%u"; char tmp[sizeof("255.255.255.255")]; - if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size) { + if ((size_t)snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]) >= size) { SET_ERRNO(ENOSPC); return (NULL); } @@ -171,7 +171,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) tp += strlen(tp); break; } - tp += sprintf(tp, "%x", words[i]); + tp += snprintf(tp, sizeof(tmp)-(tp-tmp), "%x", words[i]); } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) diff --git a/src/lib/setup_once.h b/src/lib/setup_once.h index a8cfe6b..4b0f9ce 100644 --- a/src/lib/setup_once.h +++ b/src/lib/setup_once.h @@ -91,6 +91,10 @@ # endif #endif +#ifdef HAVE_SYS_RANDOM_H +#include +#endif + #ifdef HAVE_SYS_SOCKET_H #include #endif diff --git a/src/tools/acountry.c b/src/tools/acountry.c index 00a6e67..6314e06 100644 --- a/src/tools/acountry.c +++ b/src/tools/acountry.c @@ -172,7 +172,7 @@ int main(int argc, char **argv) } buf = malloc(100); - sprintf(buf, nerd_fmt, + snprintf(buf, 100, nerd_fmt, (unsigned int)(addr.s_addr >> 24), (unsigned int)((addr.s_addr >> 16) & 255), (unsigned int)((addr.s_addr >> 8) & 255), @@ -436,7 +436,7 @@ static const struct search_list country_list[] = { { 498, "md", "Moldova" }, { 492, "mc", "Monaco" }, { 496, "mn", "Mongolia" }, - { 499, "me", "Montenegro" }, + { 499, "me", "Montenegro" }, { 500, "ms", "Montserrat" }, { 504, "ma", "Morocco" }, { 508, "mz", "Mozambique" }, diff --git a/test/dns-proto.cc b/test/dns-proto.cc index e827810..c85a7d2 100644 --- a/test/dns-proto.cc +++ b/test/dns-proto.cc @@ -16,7 +16,7 @@ std::string HexDump(std::vector data) { std::stringstream ss; for (size_t ii = 0; ii < data.size(); ii++) { char buffer[2 + 1]; - sprintf(buffer, "%02x", data[ii]); + snprintf(buffer, sizeof(buffer), "%02x", data[ii]); ss << buffer; } return ss.str(); @@ -159,17 +159,17 @@ std::string AddressToString(const void* vaddr, int len) { std::stringstream ss; if (len == 4) { char buffer[4*4 + 3 + 1]; - sprintf(buffer, "%u.%u.%u.%u", - (unsigned char)addr[0], - (unsigned char)addr[1], - (unsigned char)addr[2], - (unsigned char)addr[3]); + snprintf(buffer, sizeof(buffer), "%u.%u.%u.%u", + (unsigned char)addr[0], + (unsigned char)addr[1], + (unsigned char)addr[2], + (unsigned char)addr[3]); ss << buffer; } else if (len == 16) { for (int ii = 0; ii < 16; ii+=2) { if (ii > 0) ss << ':'; char buffer[4 + 1]; - sprintf(buffer, "%02x%02x", (unsigned char)addr[ii], (unsigned char)addr[ii+1]); + snprintf(buffer, sizeof(buffer), "%02x%02x", (unsigned char)addr[ii], (unsigned char)addr[ii+1]); ss << buffer; } } else {