forked from rpms/glibc
		
	CVE-2023-4527: Stack read overflow in getaddrinfo in no-aaaa mode (#2234714)
Resolves: #2234714
This commit is contained in:
		
							parent
							
								
									53877e8f4e
								
							
						
					
					
						commit
						a491b3f5d0
					
				
							
								
								
									
										187
									
								
								glibc-rh2234714.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								glibc-rh2234714.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,187 @@ | ||||
| commit bd77dd7e73e3530203be1c52c8a29d08270cb25d | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Wed Sep 13 14:10:56 2023 +0200 | ||||
| 
 | ||||
|     CVE-2023-4527: Stack read overflow with large TCP responses in no-aaaa mode | ||||
| 
 | ||||
|     Without passing alt_dns_packet_buffer, __res_context_search can only | ||||
|     store 2048 bytes (what fits into dns_packet_buffer).  However, | ||||
|     the function returns the total packet size, and the subsequent | ||||
|     DNS parsing code in _nss_dns_gethostbyname4_r reads beyond the end | ||||
|     of the stack-allocated buffer. | ||||
| 
 | ||||
|     Fixes commit f282cdbe7f436c75864e5640a4 ("resolv: Implement no-aaaa | ||||
|     stub resolver option") and bug 30842. | ||||
| 
 | ||||
| Conflicts: | ||||
| 	resolv/nss_dns/dns-host.c | ||||
| 	  (missing dns_packet_buffer cleanup downstream) | ||||
| 
 | ||||
| diff --git a/resolv/Makefile b/resolv/Makefile
 | ||||
| index ab8ad49b5318ad41..4f4eaf060443c128 100644
 | ||||
| --- a/resolv/Makefile
 | ||||
| +++ b/resolv/Makefile
 | ||||
| @@ -58,6 +58,7 @@ tests += \
 | ||||
|    tst-resolv-edns \ | ||||
|    tst-resolv-network \ | ||||
|    tst-resolv-noaaaa \ | ||||
| +  tst-resolv-noaaaa-vc \
 | ||||
|    tst-resolv-nondecimal \ | ||||
|    tst-resolv-res_init-multi \ | ||||
|    tst-resolv-search \ | ||||
| @@ -202,6 +203,7 @@ $(objpfx)tst-resolv-res_init-multi: $(objpfx)libresolv.so \
 | ||||
|  $(objpfx)tst-resolv-res_init-thread: $(libdl) $(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-qtypes: $(objpfx)libresolv.so $(shared-thread-library) | ||||
|  $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library) | ||||
| diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
 | ||||
| index ff0a0b6f7f1f4703..f678c7d7caa3a026 100644
 | ||||
| --- a/resolv/nss_dns/dns-host.c
 | ||||
| +++ b/resolv/nss_dns/dns-host.c
 | ||||
| @@ -392,7 +392,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
 | ||||
|    else | ||||
|      { | ||||
|        n = __res_context_search (ctx, name, C_IN, T_A, | ||||
| -				host_buffer.buf->buf, 2048, NULL,
 | ||||
| +				host_buffer.buf->buf, 2048, &host_buffer.ptr,
 | ||||
|  				NULL, NULL, NULL, NULL); | ||||
|        if (n >= 0) | ||||
|  	status = gaih_getanswer_noaaaa (host_buffer.buf, n, | ||||
| diff --git a/resolv/tst-resolv-noaaaa-vc.c b/resolv/tst-resolv-noaaaa-vc.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..9f5aebd99f2d74a2
 | ||||
| --- /dev/null
 | ||||
| +++ b/resolv/tst-resolv-noaaaa-vc.c
 | ||||
| @@ -0,0 +1,129 @@
 | ||||
| +/* Test the RES_NOAAAA resolver option with a large response.
 | ||||
| +   Copyright (C) 2022-2023 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 <errno.h>
 | ||||
| +#include <netdb.h>
 | ||||
| +#include <resolv.h>
 | ||||
| +#include <stdbool.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <support/check.h>
 | ||||
| +#include <support/check_nss.h>
 | ||||
| +#include <support/resolv_test.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +#include <support/xmemstream.h>
 | ||||
| +
 | ||||
| +/* Used to keep track of the number of queries.  */
 | ||||
| +static volatile unsigned int queries;
 | ||||
| +
 | ||||
| +/* If true, add a large TXT record at the start of the answer section.  */
 | ||||
| +static volatile bool stuff_txt;
 | ||||
| +
 | ||||
| +static void
 | ||||
| +response (const struct resolv_response_context *ctx,
 | ||||
| +          struct resolv_response_builder *b,
 | ||||
| +          const char *qname, uint16_t qclass, uint16_t qtype)
 | ||||
| +{
 | ||||
| +  /* If not using TCP, just force its use.  */
 | ||||
| +  if (!ctx->tcp)
 | ||||
| +    {
 | ||||
| +      struct resolv_response_flags flags = {.tc = true};
 | ||||
| +      resolv_response_init (b, flags);
 | ||||
| +      resolv_response_add_question (b, qname, qclass, qtype);
 | ||||
| +      return;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  /* The test needs to send four queries, the first three are used to
 | ||||
| +     grow the NSS buffer via the ERANGE handshake.  */
 | ||||
| +  ++queries;
 | ||||
| +  TEST_VERIFY (queries <= 4);
 | ||||
| +
 | ||||
| +  /* AAAA queries are supposed to be disabled.  */
 | ||||
| +  TEST_COMPARE (qtype, T_A);
 | ||||
| +  TEST_COMPARE (qclass, C_IN);
 | ||||
| +  TEST_COMPARE_STRING (qname, "example.com");
 | ||||
| +
 | ||||
| +  struct resolv_response_flags flags = {};
 | ||||
| +  resolv_response_init (b, flags);
 | ||||
| +  resolv_response_add_question (b, qname, qclass, qtype);
 | ||||
| +
 | ||||
| +  resolv_response_section (b, ns_s_an);
 | ||||
| +
 | ||||
| +  if (stuff_txt)
 | ||||
| +    {
 | ||||
| +      resolv_response_open_record (b, qname, qclass, T_TXT, 60);
 | ||||
| +      int zero = 0;
 | ||||
| +      for (int i = 0; i <= 15000; ++i)
 | ||||
| +        resolv_response_add_data (b, &zero, sizeof (zero));
 | ||||
| +      resolv_response_close_record (b);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  for (int i = 0; i < 200; ++i)
 | ||||
| +    {
 | ||||
| +      resolv_response_open_record (b, qname, qclass, qtype, 60);
 | ||||
| +      char ipv4[4] = {192, 0, 2, i + 1};
 | ||||
| +      resolv_response_add_data (b, &ipv4, sizeof (ipv4));
 | ||||
| +      resolv_response_close_record (b);
 | ||||
| +    }
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  struct resolv_test *obj = resolv_test_start
 | ||||
| +    ((struct resolv_redirect_config)
 | ||||
| +     {
 | ||||
| +       .response_callback = response
 | ||||
| +     });
 | ||||
| +
 | ||||
| +  _res.options |= RES_NOAAAA;
 | ||||
| +
 | ||||
| +  for (int do_stuff_txt = 0; do_stuff_txt < 2; ++do_stuff_txt)
 | ||||
| +    {
 | ||||
| +      queries = 0;
 | ||||
| +      stuff_txt = do_stuff_txt;
 | ||||
| +
 | ||||
| +      struct addrinfo *ai = NULL;
 | ||||
| +      int ret;
 | ||||
| +      ret = getaddrinfo ("example.com", "80",
 | ||||
| +                         &(struct addrinfo)
 | ||||
| +                         {
 | ||||
| +                           .ai_family = AF_UNSPEC,
 | ||||
| +                           .ai_socktype = SOCK_STREAM,
 | ||||
| +                         }, &ai);
 | ||||
| +
 | ||||
| +      char *expected_result;
 | ||||
| +      {
 | ||||
| +        struct xmemstream mem;
 | ||||
| +        xopen_memstream (&mem);
 | ||||
| +        for (int i = 0; i < 200; ++i)
 | ||||
| +          fprintf (mem.out, "address: STREAM/TCP 192.0.2.%d 80\n", i + 1);
 | ||||
| +        xfclose_memstream (&mem);
 | ||||
| +        expected_result = mem.buffer;
 | ||||
| +      }
 | ||||
| +
 | ||||
| +      check_addrinfo ("example.com", ai, ret, expected_result);
 | ||||
| +
 | ||||
| +      free (expected_result);
 | ||||
| +      freeaddrinfo (ai);
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  resolv_test_end (obj);
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#include <support/test-driver.c>
 | ||||
| @ -132,7 +132,7 @@ end \ | ||||
| Summary: The GNU libc libraries | ||||
| Name: glibc | ||||
| Version: %{glibcversion} | ||||
| Release: %{glibcrelease}.1 | ||||
| Release: %{glibcrelease}.2 | ||||
| 
 | ||||
| # In general, GPLv2+ is used by programs, LGPLv2+ is used for | ||||
| # libraries. | ||||
| @ -1053,6 +1053,7 @@ Patch860: glibc-rh2233338-3.patch | ||||
| Patch861: glibc-rh2233338-4.patch | ||||
| Patch862: glibc-rh2233338-5.patch | ||||
| Patch863: glibc-rh2233338-6.patch | ||||
| Patch864: glibc-rh2234714.patch | ||||
| 
 | ||||
| ############################################################################## | ||||
| # Continued list of core "glibc" package information: | ||||
| @ -2883,6 +2884,9 @@ fi | ||||
| %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared | ||||
| 
 | ||||
| %changelog | ||||
| * Wed Sep 13 2023 Florian Weimer <fweimer@redhat.com> - 2.28-236.2 | ||||
| - CVE-2023-4527: Stack read overflow in getaddrinfo in no-aaaa mode (#2234714) | ||||
| 
 | ||||
| * Mon Sep 11 2023 Florian Weimer <fweimer@redhat.com> - 2.28-236.1 | ||||
| - Always call destructors in reverse constructor order (#2233338) | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user