diff options
Diffstat (limited to '0006-resolv-Do-not-wait-for-non-existing-second-DNS-respo.patch')
-rw-r--r-- | 0006-resolv-Do-not-wait-for-non-existing-second-DNS-respo.patch | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/0006-resolv-Do-not-wait-for-non-existing-second-DNS-respo.patch b/0006-resolv-Do-not-wait-for-non-existing-second-DNS-respo.patch new file mode 100644 index 0000000..572527b --- /dev/null +++ b/0006-resolv-Do-not-wait-for-non-existing-second-DNS-respo.patch @@ -0,0 +1,232 @@ +From 6cad0f543ccac5abd35a3a617fab72a9c8c64155 Mon Sep 17 00:00:00 2001 +From: Florian Weimer <fweimer@redhat.com> +Date: Wed, 24 Jul 2024 12:06:47 +0200 +Subject: [PATCH 06/12] resolv: Do not wait for non-existing second DNS + response after error (bug 30081) + +In single-request mode, there is no second response after an error +because the second query has not been sent yet. Waiting for it +introduces an unnecessary timeout. + +Reviewed-by: DJ Delorie <dj@redhat.com> +(cherry picked from commit af625987d619388a100b153520d3ee308bda9889) +--- + NEWS | 1 + + resolv/Makefile | 3 + + resolv/res_send.c | 2 +- + resolv/tst-resolv-semi-failure.c | 133 +++++++++++++++++++++++++++++ + resolv/tst-resolv-short-response.c | 12 +++ + 5 files changed, 150 insertions(+), 1 deletion(-) + create mode 100644 resolv/tst-resolv-semi-failure.c + +diff --git a/NEWS b/NEWS +index c331604747..4156a017ac 100644 +--- a/NEWS ++++ b/NEWS +@@ -37,6 +37,7 @@ Security related changes: + The following bugs are resolved with this release: + + [29039] Corrupt DTV after reuse of a TLS module ID following dlclose with unused TLS ++ [30081] resolv: Do not wait for non-existing second DNS response after error + [30694] The iconv program no longer tells the user which given encoding name was wrong + [30709] nscd fails to build with cleanup handler if built with -fexceptions + [30721] x86_64: Fix build with --disable-multiarch +diff --git a/resolv/Makefile b/resolv/Makefile +index cca0748f9a..b53a5fcfdb 100644 +--- a/resolv/Makefile ++++ b/resolv/Makefile +@@ -106,6 +106,7 @@ tests += \ + tst-resolv-nondecimal \ + tst-resolv-res_init-multi \ + tst-resolv-search \ ++ tst-resolv-semi-failure \ + tst-resolv-short-response \ + tst-resolv-trailing \ + +@@ -300,6 +301,8 @@ $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library) + $(objpfx)tst-resolv-search: $(objpfx)libresolv.so $(shared-thread-library) ++$(objpfx)tst-resolv-semi-failure: $(objpfx)libresolv.so \ ++ $(shared-thread-library) + $(objpfx)tst-resolv-short-response: $(objpfx)libresolv.so \ + $(shared-thread-library) + $(objpfx)tst-resolv-trailing: $(objpfx)libresolv.so $(shared-thread-library) +diff --git a/resolv/res_send.c b/resolv/res_send.c +index bf4ce67b1d..b741b42cae 100644 +--- a/resolv/res_send.c ++++ b/resolv/res_send.c +@@ -1236,7 +1236,7 @@ send_dg(res_state statp, + *resplen2 = 0; + return resplen; + } +- if (buf2 != NULL) ++ if (buf2 != NULL && !single_request) + { + /* No data from the first reply. */ + resplen = 0; +diff --git a/resolv/tst-resolv-semi-failure.c b/resolv/tst-resolv-semi-failure.c +new file mode 100644 +index 0000000000..aa9798b5a7 +--- /dev/null ++++ b/resolv/tst-resolv-semi-failure.c +@@ -0,0 +1,133 @@ ++/* Test parallel failure/success responses (bug 30081). ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <https://www.gnu.org/licenses/>. */ ++ ++#include <resolv.h> ++#include <support/check.h> ++#include <support/resolv_test.h> ++#include <support/check_nss.h> ++ ++/* The rcode in the initial response. */ ++static volatile int rcode; ++ ++/* Whether to fail the initial A query (!fail_aaaa) or the initial ++ AAAA query (fail_aaaa). */ ++static volatile bool fail_aaaa; ++ ++static void ++response (const struct resolv_response_context *ctx, ++ struct resolv_response_builder *b, ++ const char *qname, uint16_t qclass, uint16_t qtype) ++{ ++ /* Handle the failing query. */ ++ if ((fail_aaaa && qtype == T_AAAA) && ctx->server_index == 0) ++ { ++ struct resolv_response_flags flags = {.rcode = rcode}; ++ resolv_response_init (b, flags); ++ return; ++ } ++ ++ /* Otherwise produce a response. */ ++ resolv_response_init (b, (struct resolv_response_flags) {}); ++ resolv_response_add_question (b, qname, qclass, qtype); ++ resolv_response_section (b, ns_s_an); ++ resolv_response_open_record (b, qname, qclass, qtype, 0); ++ switch (qtype) ++ { ++ case T_A: ++ { ++ char ipv4[4] = {192, 0, 2, 17}; ++ resolv_response_add_data (b, &ipv4, sizeof (ipv4)); ++ } ++ break; ++ case T_AAAA: ++ { ++ char ipv6[16] ++ = {0x20, 0x01, 0xd, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; ++ resolv_response_add_data (b, &ipv6, sizeof (ipv6)); ++ } ++ break; ++ default: ++ FAIL_EXIT1 ("unexpected TYPE%d query", qtype); ++ } ++ resolv_response_close_record (b); ++} ++ ++static void ++check_one (void) ++{ ++ ++ /* The buggy 1-second query timeout results in 30 seconds of delay, ++ which triggers are test timeout failure. */ ++ for (int i = 0; i < 30; ++i) ++ { ++ static const struct addrinfo hints = ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ }; ++ struct addrinfo *ai; ++ int ret = getaddrinfo ("www.example", "80", &hints, &ai); ++ const char *expected; ++ if (ret == 0 && ai->ai_next != NULL) ++ expected = ("address: STREAM/TCP 192.0.2.17 80\n" ++ "address: STREAM/TCP 2001:db8::1 80\n"); ++ else ++ /* Only one response because the AAAA lookup failure is ++ treated as an ignoreable error. */ ++ expected = "address: STREAM/TCP 192.0.2.17 80\n"; ++ check_addrinfo ("www.example", ai, ret, expected); ++ if (ret == 0) ++ freeaddrinfo (ai); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ for (int do_single_lookup = 0; do_single_lookup < 2; ++do_single_lookup) ++ { ++ struct resolv_test *aux = resolv_test_start ++ ((struct resolv_redirect_config) ++ { ++ .response_callback = response, ++ }); ++ ++ if (do_single_lookup) ++ _res.options |= RES_SNGLKUP; ++ ++ for (int do_fail_aaaa = 0; do_fail_aaaa < 2; ++do_fail_aaaa) ++ { ++ fail_aaaa = do_fail_aaaa; ++ ++ rcode = 2; /* SERVFAIL. */ ++ check_one (); ++ ++ rcode = 4; /* NOTIMP. */ ++ check_one (); ++ ++ rcode = 5; /* REFUSED. */ ++ check_one (); ++ } ++ ++ resolv_test_end (aux); ++ } ++ ++ return 0; ++} ++ ++#include <support/test-driver.c> +diff --git a/resolv/tst-resolv-short-response.c b/resolv/tst-resolv-short-response.c +index cf1e39876f..be354ae1c7 100644 +--- a/resolv/tst-resolv-short-response.c ++++ b/resolv/tst-resolv-short-response.c +@@ -81,6 +81,18 @@ check_one (void) + check_hostent ("www.example", gethostbyname2 ("www.example", AF_INET6), + "name: www.example\n" + "address: 2001:db8::1\n"); ++ static const struct addrinfo hints = ++ { ++ .ai_family = AF_UNSPEC, ++ .ai_socktype = SOCK_STREAM, ++ }; ++ struct addrinfo *ai; ++ int ret = getaddrinfo ("www.example", "80", &hints, &ai); ++ check_addrinfo ("www.example", ai, ret, ++ "address: STREAM/TCP 192.0.2.17 80\n" ++ "address: STREAM/TCP 2001:db8::1 80\n"); ++ if (ret == 0) ++ freeaddrinfo (ai); + } + } + +-- +2.33.0 + |