[glibc] resolv: Test case for accepting mismatching, corrupted packets
Florian Weimer via Glibc-cvs <[email protected]>
| Newsgroups | gmane.comp.lib.glibc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=40ddd85420c11446d5b670a6245e076b11f3173b commit 40ddd85420c11446d5b670a6245e076b11f3173b Author: Florian Weimer <[email protected]> Date: Sat Aug 15 12:03:35 2026 +0200 resolv: Test case for accepting mismatching, corrupted packets The test skeleton was auto-generated. I think this is fine because the harness is so specific to glibc. Assisted-by: LLM Reviewed-by: Adhemerval Zanella <[email protected]> Diff: --- resolv/Makefile | 3 + resolv/tst-resolv-querymatch-short.c | 109 +++++++++++++++++++++++++++++++++++ support/resolv_test.c | 6 ++ 3 files changed, 118 insertions(+) diff --git a/resolv/Makefile b/resolv/Makefile index 28f6ba6c3b..e53a2b9bce 100644 --- a/resolv/Makefile +++ b/resolv/Makefile @@ -123,6 +123,7 @@ tests += \ tst-resolv-noaaaa \ tst-resolv-noaaaa-vc \ tst-resolv-nondecimal \ + tst-resolv-querymatch-short \ tst-resolv-res_init-failure \ tst-resolv-res_init-multi \ tst-resolv-search \ @@ -326,6 +327,8 @@ $(objpfx)tst-resolv-no-search: $(objpfx)libresolv.so $(shared-thread-library) $(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library) $(objpfx)tst-resolv-noaaaa-vc: $(objpfx)libresolv.so $(shared-thread-library) $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library) +$(objpfx)tst-resolv-querymatch-short: $(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) diff --git a/resolv/tst-resolv-querymatch-short.c b/resolv/tst-resolv-querymatch-short.c new file mode 100644 index 0000000000..d9f9409622 --- /dev/null +++ b/resolv/tst-resolv-querymatch-short.c @@ -0,0 +1,109 @@ +/* Test res_queriesmatch buffer handling (bug 34345, bug 34346). + Copyright (C) 2026 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 <netdb.h> +#include <resolv.h> +#include <support/check.h> +#include <support/check_nss.h> +#include <support/resolv_test.h> + +static void +response (const struct resolv_response_context *ctx, + struct resolv_response_builder *b, + const char *qname, uint16_t qclass, uint16_t qtype) +{ + switch (ctx->server_index) + { + case 0: + { + struct resolv_response_flags flags = { .rcode = 3 }; /* NXDOMAIN. */ + resolv_response_init (b, flags); + resolv_response_add_question (b, qname, qclass, qtype); + + /* Cause a mismatch in the transaction ID. */ + *resolv_response_buffer (b) ^= 1; + } + break; + + case 1: + { + struct resolv_response_flags flags = { .rcode = 3 }; /* NXDOMAIN. */ + resolv_response_init (b, flags); + resolv_response_add_question (b, qname, qclass, qtype); + + /* Truncate the packet. If bug 34346 is present, this + response will be accepted because the final byte (which is + overread) has the expected value, carried over from the + previous response. With bug 34345, the response is + accepted (as NXDOMAIN) because the packet is corrupt. */ + resolv_response_set_buffer (b, + resolv_response_buffer (b), + resolv_response_length (b) - 1); + + } + break; + + case 2: + { + /* Finally, provide a valid response. With either bug + present, this is never reached because the stub resolver + uses the response from the second server above. */ + 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); + char ipv4[4] = { 192, 0, 2, 17 }; + resolv_response_add_data (b, &ipv4, sizeof (ipv4)); + resolv_response_close_record (b); + } + break; + } +} + +static int +do_test (void) +{ + struct resolv_test *aux = resolv_test_start + ((struct resolv_redirect_config) + { + .response_callback = response, + }); + + /* Reduce test run time. The test hits multiple timeouts as it + switches between name server. */ + _res.retrans = 1; + _res.retry = 1; + + struct addrinfo hints = + { + .ai_family = AF_INET, + .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"); + if (ret == 0) + freeaddrinfo (ai); + + resolv_test_end (aux); + + return 0; +} + +#include <support/test-driver.c> diff --git a/support/resolv_test.c b/support/resolv_test.c index 4bb642f439..fd97ba1ee4 100644 --- a/support/resolv_test.c +++ b/support/resolv_test.c @@ -441,8 +441,14 @@ resolv_response_set_buffer (struct resolv_response_builder *b, if (length > max_response_length) FAIL_EXIT1 ("resolv_response_set_buffer: length %zu exceeds maximum %d", length, max_response_length); + if (b->current_rdata_offset != 0) + FAIL_EXIT1 ("resolv_response_set_buffer: called with pending RDATA"); memmove (b->buffer, data, length); b->offset = length; + + /* The cached compression offsets are likely invalid now. */ + tdestroy (b->compression_offsets, free); + b->compression_offsets = NULL; } struct resolv_response_builder *