The branch, master has been updated via e124906 cmake: Fix tests on Solaris. via 4af3e98 torture: Fix socket directory name. via 3703225 tests: Fix test_res_ninit() with IPv4 only support. via 1e5333c rwrap: Fix symbol binding on Solaris. via e148623 tests: Use the right array size in tests. via de4d1f4 rwrap: Don't use htons for bitfields. via 2f67bf0 rwrap: Explicitly zero out sin_zero to silence gcc warnings. via b813639 tests: Call res_nclose() in test_res_query_search.c. via a5ddc99 rwrap: Close the resolv.conf file handle. via 0bfdc27 rwrap: Free IPv6 name servers on close. from f9abdf9 rwrap: Move NEXT_KEY out of the NDEBUG ifdef.
http://gitweb.samba.org/?p=resolv_wrapper.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit e12490601efef47cae766fb437c8f070a5acc19f Author: Andreas Schneider <a...@samba.org> Date: Thu Oct 23 12:41:52 2014 +0200 cmake: Fix tests on Solaris. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit 4af3e98588580c1c460e40e2e4b77f8502be65c4 Author: Andreas Schneider <a...@samba.org> Date: Thu Oct 23 12:30:50 2014 +0200 torture: Fix socket directory name. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit 3703225a10919cae84806b86915cd4ba832488dc Author: Andreas Schneider <a...@samba.org> Date: Thu Oct 23 07:51:04 2014 +0200 tests: Fix test_res_ninit() with IPv4 only support. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit 1e5333cb1ea789f1e5cc01433ec7cf01e4ec530f Author: Andreas Schneider <a...@samba.org> Date: Thu Oct 23 07:46:53 2014 +0200 rwrap: Fix symbol binding on Solaris. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit e1486231cd4584c1c3b797457d3e0b9a5e0e1430 Author: Jakub Hrozek <jakub.hro...@gmail.com> Date: Tue Oct 21 18:42:44 2014 +0200 tests: Use the right array size in tests. Several unit tests used the wrong array size, which might cause buffer overflows. This patch unifies on using sizeof(array) since all the arrays are allocated on stack. CID #68270 CID #68269 CID #68267 CID #68265 Signed-off-by: Jakub Hrozek <jakub.hro...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit de4d1f40645d383fccce4693a1323744636b769a Author: Jakub Hrozek <jakub.hro...@gmail.com> Date: Tue Oct 21 17:23:30 2014 +0200 rwrap: Don't use htons for bitfields. On FreeBSD, using htons to set the bitfield led to warnings such as: resolv_wrapper.c:162:8: warning: implicit truncation from '__uint16_t' (aka 'unsigned short') to bitfield changes value from 256 to 0 [-Wbitfield-constant-conversion] h->qr = htons(1); /* response flag */ ^ ~~~~~~~~ Signed-off-by: Jakub Hrozek <jakub.hro...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit 2f67bf076f7a9f2d85ec24c027fa9d24de5d1e64 Author: Jakub Hrozek <jakub.hro...@gmail.com> Date: Tue Oct 21 15:34:28 2014 +0200 rwrap: Explicitly zero out sin_zero to silence gcc warnings. On some platforms, failure to set the sin_zero structure lead to warnings such as: resolv_wrapper.c:969:5: warning: missing initializer for field ‘sin_zero’ of ‘struct sockaddr_in’ [-Wmissing-field-initializers] }; ^ In file included from /usr/include/arpa/inet.h:22:0, from /.../source/src/resolv_wrapper.c:38: Signed-off-by: Jakub Hrozek <jakub.hro...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit b813639c1d87369d0de69b3d86ca3aabd8652eba Author: Jakub Hrozek <jakub.hro...@gmail.com> Date: Tue Oct 21 15:27:54 2014 +0200 tests: Call res_nclose() in test_res_query_search.c. The res_query and res_nsearch unit tests didn't call res_nclose as appropriate, leading to a resource leak. Signed-off-by: Jakub Hrozek <jakub.hro...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit a5ddc993bb098390df324471fda5d70e9b42a361 Author: Jakub Hrozek <jakub.hro...@gmail.com> Date: Tue Oct 21 15:11:16 2014 +0200 rwrap: Close the resolv.conf file handle. CID #68264 The file descriptor of resolv.conf wasn't closed properly. Signed-off-by: Jakub Hrozek <jakub.hro...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit 0bfdc27620b237f17a0a6c089c616df3e891cf9f Author: Jakub Hrozek <jakub.hro...@gmail.com> Date: Tue Oct 21 15:00:36 2014 +0200 rwrap: Free IPv6 name servers on close. rwrap's res_ninit allocates IPv6 name servers, but res_nclose didn't free them, leading to a resource leak detectable with valgrind. Signed-off-by: Jakub Hrozek <jakub.hro...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> ----------------------------------------------------------------------- Summary of changes: ConfigureChecks.cmake | 19 ++++++++++++++----- config.h.cmake | 2 ++ src/resolv_wrapper.c | 34 +++++++++++++++++++++++++++++++--- tests/CMakeLists.txt | 5 ++++- tests/test_dns_fake.c | 37 ++++++++++++++++++++----------------- tests/test_res_init.c | 4 +++- tests/test_res_query_search.c | 18 ++++++++++++------ tests/torture.c | 2 +- 8 files changed, 87 insertions(+), 34 deletions(-) Changeset truncated at 500 lines: diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index 2633d23..6dbfc88 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -52,11 +52,14 @@ check_include_file(resolv.h HAVE_RESOLV_H) # FUNCTIONS find_library(RESOLV_LIRBRARY resolv) -check_library_exists(${RESOLV_LIRBRARY} res_send "" RES_SEND_IN_LIBRESOLV) -check_library_exists(${RESOLV_LIRBRARY} __res_send "" __RES_SEND_IN_LIBRESOLV) -if (RESOLV_LIRBRARY AND RES_SEND_IN_LIBRESOLV OR __RES_SEND_IN_LIBRESOLV) - set(HAVE_LIBRESOLV TRUE) - set(CMAKE_REQUIRED_LIBRARIES ${RESOLV_LIRBRARY}) + +if (RESOLV_LIRBRARY) + check_library_exists(${RESOLV_LIRBRARY} res_send "" RES_SEND_IN_LIBRESOLV) + check_library_exists(${RESOLV_LIRBRARY} __res_send "" __RES_SEND_IN_LIBRESOLV) + if (RES_SEND_IN_LIBRESOLV OR __RES_SEND_IN_LIBRESOLV) + set(HAVE_LIBRESOLV TRUE) + set(CMAKE_REQUIRED_LIBRARIES ${RESOLV_LIRBRARY}) + endif() endif() check_function_exists(res_init HAVE_RES_INIT) @@ -64,12 +67,18 @@ check_function_exists(__res_init HAVE___RES_INIT) check_function_exists(res_ninit HAVE_RES_NINIT) check_function_exists(__res_ninit HAVE___RES_NINIT) +if (RESOLV_LIRBRARY) + check_library_exists(${RESOLV_LIRBRARY} res_ninit "" HAVE_RES_NINIT_IN_LIBRESOLV) +endif() check_function_exists(res_close HAVE_RES_CLOSE) check_function_exists(__res_close HAVE___RES_CLOSE) check_function_exists(res_nclose HAVE_RES_NCLOSE) check_function_exists(__res_nclose HAVE___RES_NCLOSE) +if (RESOLV_LIRBRARY) + check_library_exists(${RESOLV_LIRBRARY} res_nclose "" HAVE_RES_NCLOSE_IN_LIBRESOLV) +endif() check_function_exists(res_query HAVE_RES_QUERY) check_function_exists(__res_query HAVE___RES_QUERY) diff --git a/config.h.cmake b/config.h.cmake index 9d4dca0..aad83e3 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -22,12 +22,14 @@ #cmakedefine HAVE___RES_INIT 1 #cmakedefine HAVE_RES_NINIT 1 +#cmakedefine HAVE_RES_NINIT_IN_LIBRESOLV 1 #cmakedefine HAVE___RES_NINIT 1 #cmakedefine HAVE_RES_CLOSE 1 #cmakedefine HAVE___RES_CLOSE 1 #cmakedefine HAVE_RES_NCLOSE 1 +#cmakedefine HAVE_RES_NCLOSE_IN_LIBRESOLV 1 #cmakedefine HAVE___RES_NCLOSE 1 #cmakedefine HAVE_RES_QUERY 1 diff --git a/src/resolv_wrapper.c b/src/resolv_wrapper.c index 8cc1e04..8d0d67e 100644 --- a/src/resolv_wrapper.c +++ b/src/resolv_wrapper.c @@ -125,6 +125,10 @@ static void rwrap_log(enum rwrap_dbglvl_e dbglvl, } #endif /* NDEBUG RWRAP_LOG */ +#ifndef SAFE_FREE +#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); (x)=NULL;} } while(0) +#endif + #define NEXT_KEY(buf, key) do { \ (key) = (buf) ? strpbrk((buf), " \t") : NULL; \ if ((key) != NULL) { \ @@ -159,9 +163,9 @@ static ssize_t rwrap_fake_header(uint8_t **header_blob, size_t remaining, h = (HEADER *) hb; h->id = res_randomid(); /* random query ID */ - h->qr = htons(1); /* response flag */ - h->rd = htons(1); /* recursion desired */ - h->ra = htons(1); /* resursion available */ + h->qr = 1; /* response flag */ + h->rd = 1; /* recursion desired */ + h->ra = 1; /* resursion available */ h->qdcount = htons(1); /* no. of questions */ h->ancount = htons(answers); /* no. of answers */ @@ -828,7 +832,12 @@ static int libc_res_init(void) static int libc_res_ninit(struct __res_state *state) { #if defined(HAVE_RES_NINIT) + +#if defined(HAVE_RES_NINIT_IN_LIBRESOLV) + rwrap_load_lib_function(RWRAP_LIBRESOLV, res_ninit); +#else /* HAVE_RES_NINIT_IN_LIBRESOLV */ rwrap_load_lib_function(RWRAP_LIBC, res_ninit); +#endif /* HAVE_RES_NINIT_IN_LIBRESOLV */ return rwrap.fns.libc_res_ninit(state); #elif defined(HAVE___RES_NINIT) @@ -843,7 +852,12 @@ static int libc_res_ninit(struct __res_state *state) static void libc_res_nclose(struct __res_state *state) { #if defined(HAVE_RES_NCLOSE) + +#if defined(HAVE_RES_NCLOSE_IN_LIBRESOLV) + rwrap_load_lib_function(RWRAP_LIBRESOLV, res_nclose); +#else /* HAVE_RES_NCLOSE_IN_LIBRESOLV */ rwrap_load_lib_function(RWRAP_LIBC, res_nclose); +#endif /* HAVE_RES_NCLOSE_IN_LIBRESOLV */ rwrap.fns.libc_res_nclose(state); #elif defined(HAVE___RES_NCLOSE) @@ -966,6 +980,7 @@ static int rwrap_parse_resolv_conf(struct __res_state *state, .sin_family = AF_INET, .sin_addr = a, .sin_port = htons(53), + .sin_zero = { 0 }, }; state->nscount++; @@ -980,6 +995,7 @@ static int rwrap_parse_resolv_conf(struct __res_state *state, sa6 = malloc(sizeof(*sa6)); if (sa6 == NULL) { + fclose(fp); return -1; } @@ -1019,9 +1035,11 @@ static int rwrap_parse_resolv_conf(struct __res_state *state, RWRAP_LOG(RWRAP_LOG_ERROR, "Reading from %s failed", resolv_conf); + fclose(fp); return -1; } + fclose(fp); return 0; } @@ -1100,6 +1118,16 @@ int __res_init(void) static void rwrap_res_nclose(struct __res_state *state) { +#ifdef HAVE_RESOLV_IPV6_NSADDRS + int i; + + if (state != NULL) { + for (i = 0; i < state->_u._ext.nscount; i++) { + SAFE_FREE(state->_u._ext.nsaddrs[i]); + state->_u._ext.nssocks[i] = 0; + } + } +#endif libc_res_nclose(state); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index acd675f..fb8876c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -33,7 +33,10 @@ set(PRELOAD_LIBS ${RESOLV_WRAPPER_LOCATION}) # Some tests require socket_wrapper as well. find_package(socket_wrapper) -if (HAVE_LIBRESOLV AND SOCKET_WRAPPER_LIBRARY) + +# On Solaris the socket functions are compiled into libresolv.so so we can't preload +# socket_wrapper. Only faking will work! +if (HAVE_LIBRESOLV AND SOCKET_WRAPPER_LIBRARY AND NOT SOLARIS) set(RWRAP_TESTS ${RWRAP_TESTS} test_res_query_search) set(PRELOAD_LIBS ${RESOLV_WRAPPER_LOCATION}:${SOCKET_WRAPPER_LIBRARY}) endif() diff --git a/tests/test_dns_fake.c b/tests/test_dns_fake.c index 260a8e6..591b3e1 100644 --- a/tests/test_dns_fake.c +++ b/tests/test_dns_fake.c @@ -66,10 +66,10 @@ static void test_res_fake_a_query(void **state) assert_int_equal(rv, 0); rv = res_nquery(&dnsstate, "cwrap.org", ns_c_in, ns_t_a, - answer, ANSIZE); + answer, sizeof(answer)); assert_int_not_equal(rv, -1); - ns_initparse(answer, 256, &handle); + ns_initparse(answer, sizeof(answer), &handle); /* The query must finish w/o an error, have one answer and the answer * must be a parseable RR of type A and have the address that our * fake hosts file contains @@ -78,7 +78,8 @@ static void test_res_fake_a_query(void **state) assert_int_equal(ns_msg_count(handle, ns_s_an), 1); assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0); assert_int_equal(ns_rr_type(rr), ns_t_a); - assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr), addr, 256)); + assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr), + addr, sizeof(addr))); assert_string_equal(addr, "127.0.0.21"); } @@ -96,10 +97,10 @@ static void test_res_fake_a_query_notfound(void **state) assert_int_equal(rv, 0); rv = res_nquery(&dnsstate, "nosuchentry.org", ns_c_in, ns_t_a, - answer, ANSIZE); + answer, sizeof(answer)); assert_int_not_equal(rv, -1); - ns_initparse(answer, 256, &handle); + ns_initparse(answer, sizeof(answer), &handle); /* The query must finish w/o an error and have no answer */ assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror); assert_int_equal(ns_msg_count(handle, ns_s_an), 0); @@ -121,10 +122,10 @@ static void test_res_fake_aaaa_query(void **state) assert_int_equal(rv, 0); rv = res_nquery(&dnsstate, "cwrap6.org", ns_c_in, ns_t_aaaa, - answer, ANSIZE); + answer, sizeof(answer)); assert_int_not_equal(rv, -1); - ns_initparse(answer, 256, &handle); + ns_initparse(answer, sizeof(answer), &handle); /* The query must finish w/o an error, have one answer and the answer * must be a parseable RR of type AAAA and have the address that our * fake hosts file contains @@ -133,7 +134,8 @@ static void test_res_fake_aaaa_query(void **state) assert_int_equal(ns_msg_count(handle, ns_s_an), 1); assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0); assert_int_equal(ns_rr_type(rr), ns_t_aaaa); - assert_non_null(inet_ntop(AF_INET6, ns_rr_rdata(rr), addr, 256)); + assert_non_null(inet_ntop(AF_INET6, ns_rr_rdata(rr), + addr, sizeof(addr))); assert_string_equal(addr, "2a00:1450:4013:c01::63"); } @@ -151,10 +153,10 @@ static void test_res_fake_aaaa_query_notfound(void **state) assert_int_equal(rv, 0); rv = res_nquery(&dnsstate, "nosuchentry.org", ns_c_in, ns_t_aaaa, - answer, ANSIZE); + answer, sizeof(answer)); assert_int_not_equal(rv, -1); - ns_initparse(answer, 256, &handle); + ns_initparse(answer, sizeof(answer), &handle); /* The query must finish w/o an error and have no answer */ assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror); assert_int_equal(ns_msg_count(handle, ns_s_an), 0); @@ -180,10 +182,10 @@ static void test_res_fake_srv_query(void **state) assert_int_equal(rv, 0); rv = res_nquery(&dnsstate, "_ldap._tcp.cwrap.org", ns_c_in, ns_t_srv, - answer, ANSIZE); + answer, sizeof(answer)); assert_int_not_equal(rv, -1); - ns_initparse(answer, 256, &handle); + ns_initparse(answer, sizeof(answer), &handle); /* * The query must finish w/o an error, have one answer and the answer @@ -238,10 +240,10 @@ static void test_res_fake_srv_query_minimal(void **state) assert_int_equal(rv, 0); rv = res_nquery(&dnsstate, "_krb5._tcp.cwrap.org", ns_c_in, ns_t_srv, - answer, ANSIZE); + answer, sizeof(answer)); assert_int_not_equal(rv, -1); - ns_initparse(answer, 256, &handle); + ns_initparse(answer, sizeof(answer), &handle); /* * The query must finish w/o an error, have one answer and the answer @@ -293,10 +295,10 @@ static void test_res_fake_soa_query(void **state) assert_int_equal(rv, 0); rv = res_nquery(&dnsstate, "cwrap.org", ns_c_in, ns_t_soa, - answer, ANSIZE); + answer, sizeof(answer)); assert_int_not_equal(rv, -1); - ns_initparse(answer, 256, &handle); + ns_initparse(answer, sizeof(answer), &handle); /* * The query must finish w/o an error, have one answer and the answer @@ -356,10 +358,11 @@ static void test_res_fake_cname_query(void **state) assert_int_equal(rv, 0); rv = res_nquery(&dnsstate, "cwrap.org", ns_c_in, ns_t_cname, - answer, ANSIZE); + answer, sizeof(answer)); assert_int_not_equal(rv, -1); ns_initparse(answer, 256, &handle); + ns_initparse(answer, sizeof(answer), &handle); /* * The query must finish w/o an error, have one answer and the answer diff --git a/tests/test_res_init.c b/tests/test_res_init.c index 0e2d58e..e42b8a4 100644 --- a/tests/test_res_init.c +++ b/tests/test_res_init.c @@ -162,7 +162,7 @@ static void test_res_ninit(void **state) assert_int_equal(dnsstate.nsaddr_list[2].sin_port, htons(53)); inet_ntop(AF_INET, &(dnsstate.nsaddr_list[2].sin_addr), straddr, INET6_ADDRSTRLEN); - assert_string_equal(nameservers[2], straddr); + assert_string_equal(nameservers[3], straddr); #else /* IPv6 */ sa6 = dnsstate._u._ext.nsaddrs[0]; @@ -171,6 +171,8 @@ static void test_res_ninit(void **state) inet_ntop(AF_INET6, &(sa6->sin6_addr), straddr, INET6_ADDRSTRLEN); assert_string_equal(nameservers[2], straddr); #endif + + res_nclose(&dnsstate); } static void test_res_ninit_enoent(void **state) diff --git a/tests/test_res_query_search.c b/tests/test_res_query_search.c index 2188f76..9eef6e4 100644 --- a/tests/test_res_query_search.c +++ b/tests/test_res_query_search.c @@ -78,10 +78,10 @@ static void test_res_query(void **state) assert_int_equal(rv, 0); rv = res_nquery(&dnsstate, "www.cwrap.org", ns_c_in, ns_t_a, - answer, ANSIZE); + answer, sizeof(answer)); assert_int_not_equal(rv, -1); - ns_initparse(answer, 256, &handle); + ns_initparse(answer, sizeof(answer), &handle); /* * The query must finish w/o an error, have one answer and the answer * must be a parseable RR of type A and have the address that our @@ -91,8 +91,11 @@ static void test_res_query(void **state) assert_int_equal(ns_msg_count(handle, ns_s_an), 1); assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0); assert_int_equal(ns_rr_type(rr), ns_t_a); - assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr), addr, 256)); + assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr), + addr, sizeof(addr))); assert_string_equal(addr, "127.0.10.10"); + + res_nclose(&dnsstate); } static void test_res_search(void **state) @@ -111,10 +114,10 @@ static void test_res_search(void **state) assert_int_equal(rv, 0); rv = res_nsearch(&dnsstate, "www.cwrap.org", ns_c_in, ns_t_a, - answer, ANSIZE); + answer, sizeof(answer)); assert_int_not_equal(rv, -1); - ns_initparse(answer, 256, &handle); + ns_initparse(answer, sizeof(answer), &handle); /* The query must finish w/o an error, have one answer and the answer * must be a parseable RR of type A and have the address that our * test server sends @@ -123,8 +126,11 @@ static void test_res_search(void **state) assert_int_equal(ns_msg_count(handle, ns_s_an), 1); assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0); assert_int_equal(ns_rr_type(rr), ns_t_a); - assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr), addr, 256)); + assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr), + addr, sizeof(addr))); assert_string_equal(addr, "127.0.10.10"); + + res_nclose(&dnsstate); } int main(void) diff --git a/tests/torture.c b/tests/torture.c index baeb276..8eb19b5 100644 --- a/tests/torture.c +++ b/tests/torture.c @@ -55,7 +55,7 @@ #define TORTURE_DNS_SRV_IPV6 "fd00::5357:5f0a" #define TORTURE_DNS_SRV_PORT 53 -#define TORTURE_SOCKET_DIR "/tmp/test_socket_wrapper_XXXXXX" +#define TORTURE_SOCKET_DIR "/tmp/test_resolv_wrapper_XXXXXX" #define TORTURE_DNS_SRV_PIDFILE "dns_srv.pid" #define TORTURE_PCAP_FILE "socket_trace.pcap" -- Resolv Wrapper Repository