]> git.ipfire.org Git - people/mlorenz/ipfire-2.x.git/blame - src/patches/glibc-2.38/0019-CVE-2023-4527-Stack-read-overflow-with-large-TCP-res.patch
glibc: Import patches from upstream
[people/mlorenz/ipfire-2.x.git] / src / patches / glibc-2.38 / 0019-CVE-2023-4527-Stack-read-overflow-with-large-TCP-res.patch
CommitLineData
b9215da1
MT
1From b25508dd774b617f99419bdc3cf2ace4560cd2d6 Mon Sep 17 00:00:00 2001
2From: Florian Weimer <fweimer@redhat.com>
3Date: Wed, 13 Sep 2023 14:10:56 +0200
4Subject: [PATCH 19/27] CVE-2023-4527: Stack read overflow with large TCP
5 responses in no-aaaa mode
6
7Without passing alt_dns_packet_buffer, __res_context_search can only
8store 2048 bytes (what fits into dns_packet_buffer). However,
9the function returns the total packet size, and the subsequent
10DNS parsing code in _nss_dns_gethostbyname4_r reads beyond the end
11of the stack-allocated buffer.
12
13Fixes commit f282cdbe7f436c75864e5640a4 ("resolv: Implement no-aaaa
14stub resolver option") and bug 30842.
15
16(cherry picked from commit bd77dd7e73e3530203be1c52c8a29d08270cb25d)
17---
18 NEWS | 9 +++
19 resolv/Makefile | 2 +
20 resolv/nss_dns/dns-host.c | 2 +-
21 resolv/tst-resolv-noaaaa-vc.c | 129 ++++++++++++++++++++++++++++++++++
22 4 files changed, 141 insertions(+), 1 deletion(-)
23 create mode 100644 resolv/tst-resolv-noaaaa-vc.c
24
25diff --git a/NEWS b/NEWS
26index 64596d5d09..dfee278a9c 100644
27--- a/NEWS
28+++ b/NEWS
29@@ -7,12 +7,21 @@ using `glibc' in the "product" field.
30 \f
31 Version 2.38.1
32
33+Security related changes:
34+
35+ CVE-2023-4527: If the system is configured in no-aaaa mode via
36+ /etc/resolv.conf, getaddrinfo is called for the AF_UNSPEC address
37+ family, and a DNS response is received over TCP that is larger than
38+ 2048 bytes, getaddrinfo may potentially disclose stack contents via
39+ the returned address data, or crash.
40+
41 The following bugs are resolved with this release:
42
43 [30723] posix_memalign repeatedly scans long bin lists
44 [30785] Always call destructors in reverse constructor order
45 [30804] F_GETLK, F_SETLK, and F_SETLKW value change for powerpc64 with
46 -D_FILE_OFFSET_BITS=64
47+ [30842] Stack read overflow in getaddrinfo in no-aaaa mode (CVE-2023-4527)
48
49 \f
50 Version 2.38
51diff --git a/resolv/Makefile b/resolv/Makefile
52index 054b1fa36c..2f99eb3862 100644
53--- a/resolv/Makefile
54+++ b/resolv/Makefile
55@@ -102,6 +102,7 @@ tests += \
56 tst-resolv-invalid-cname \
57 tst-resolv-network \
58 tst-resolv-noaaaa \
59+ tst-resolv-noaaaa-vc \
60 tst-resolv-nondecimal \
61 tst-resolv-res_init-multi \
62 tst-resolv-search \
63@@ -293,6 +294,7 @@ $(objpfx)tst-resolv-res_init-thread: $(objpfx)libresolv.so \
64 $(objpfx)tst-resolv-invalid-cname: $(objpfx)libresolv.so \
65 $(shared-thread-library)
66 $(objpfx)tst-resolv-noaaaa: $(objpfx)libresolv.so $(shared-thread-library)
67+$(objpfx)tst-resolv-noaaaa-vc: $(objpfx)libresolv.so $(shared-thread-library)
68 $(objpfx)tst-resolv-nondecimal: $(objpfx)libresolv.so $(shared-thread-library)
69 $(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library)
70 $(objpfx)tst-resolv-rotate: $(objpfx)libresolv.so $(shared-thread-library)
71diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c
72index 1d60c51f5e..5d0ab30de6 100644
73--- a/resolv/nss_dns/dns-host.c
74+++ b/resolv/nss_dns/dns-host.c
75@@ -427,7 +427,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
76 {
77 n = __res_context_search (ctx, name, C_IN, T_A,
78 dns_packet_buffer, sizeof (dns_packet_buffer),
79- NULL, NULL, NULL, NULL, NULL);
80+ &alt_dns_packet_buffer, NULL, NULL, NULL, NULL);
81 if (n >= 0)
82 status = gaih_getanswer_noaaaa (alt_dns_packet_buffer, n,
83 &abuf, pat, errnop, herrnop, ttlp);
84diff --git a/resolv/tst-resolv-noaaaa-vc.c b/resolv/tst-resolv-noaaaa-vc.c
85new file mode 100644
86index 0000000000..9f5aebd99f
87--- /dev/null
88+++ b/resolv/tst-resolv-noaaaa-vc.c
89@@ -0,0 +1,129 @@
90+/* Test the RES_NOAAAA resolver option with a large response.
91+ Copyright (C) 2022-2023 Free Software Foundation, Inc.
92+ This file is part of the GNU C Library.
93+
94+ The GNU C Library is free software; you can redistribute it and/or
95+ modify it under the terms of the GNU Lesser General Public
96+ License as published by the Free Software Foundation; either
97+ version 2.1 of the License, or (at your option) any later version.
98+
99+ The GNU C Library is distributed in the hope that it will be useful,
100+ but WITHOUT ANY WARRANTY; without even the implied warranty of
101+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
102+ Lesser General Public License for more details.
103+
104+ You should have received a copy of the GNU Lesser General Public
105+ License along with the GNU C Library; if not, see
106+ <https://www.gnu.org/licenses/>. */
107+
108+#include <errno.h>
109+#include <netdb.h>
110+#include <resolv.h>
111+#include <stdbool.h>
112+#include <stdlib.h>
113+#include <support/check.h>
114+#include <support/check_nss.h>
115+#include <support/resolv_test.h>
116+#include <support/support.h>
117+#include <support/xmemstream.h>
118+
119+/* Used to keep track of the number of queries. */
120+static volatile unsigned int queries;
121+
122+/* If true, add a large TXT record at the start of the answer section. */
123+static volatile bool stuff_txt;
124+
125+static void
126+response (const struct resolv_response_context *ctx,
127+ struct resolv_response_builder *b,
128+ const char *qname, uint16_t qclass, uint16_t qtype)
129+{
130+ /* If not using TCP, just force its use. */
131+ if (!ctx->tcp)
132+ {
133+ struct resolv_response_flags flags = {.tc = true};
134+ resolv_response_init (b, flags);
135+ resolv_response_add_question (b, qname, qclass, qtype);
136+ return;
137+ }
138+
139+ /* The test needs to send four queries, the first three are used to
140+ grow the NSS buffer via the ERANGE handshake. */
141+ ++queries;
142+ TEST_VERIFY (queries <= 4);
143+
144+ /* AAAA queries are supposed to be disabled. */
145+ TEST_COMPARE (qtype, T_A);
146+ TEST_COMPARE (qclass, C_IN);
147+ TEST_COMPARE_STRING (qname, "example.com");
148+
149+ struct resolv_response_flags flags = {};
150+ resolv_response_init (b, flags);
151+ resolv_response_add_question (b, qname, qclass, qtype);
152+
153+ resolv_response_section (b, ns_s_an);
154+
155+ if (stuff_txt)
156+ {
157+ resolv_response_open_record (b, qname, qclass, T_TXT, 60);
158+ int zero = 0;
159+ for (int i = 0; i <= 15000; ++i)
160+ resolv_response_add_data (b, &zero, sizeof (zero));
161+ resolv_response_close_record (b);
162+ }
163+
164+ for (int i = 0; i < 200; ++i)
165+ {
166+ resolv_response_open_record (b, qname, qclass, qtype, 60);
167+ char ipv4[4] = {192, 0, 2, i + 1};
168+ resolv_response_add_data (b, &ipv4, sizeof (ipv4));
169+ resolv_response_close_record (b);
170+ }
171+}
172+
173+static int
174+do_test (void)
175+{
176+ struct resolv_test *obj = resolv_test_start
177+ ((struct resolv_redirect_config)
178+ {
179+ .response_callback = response
180+ });
181+
182+ _res.options |= RES_NOAAAA;
183+
184+ for (int do_stuff_txt = 0; do_stuff_txt < 2; ++do_stuff_txt)
185+ {
186+ queries = 0;
187+ stuff_txt = do_stuff_txt;
188+
189+ struct addrinfo *ai = NULL;
190+ int ret;
191+ ret = getaddrinfo ("example.com", "80",
192+ &(struct addrinfo)
193+ {
194+ .ai_family = AF_UNSPEC,
195+ .ai_socktype = SOCK_STREAM,
196+ }, &ai);
197+
198+ char *expected_result;
199+ {
200+ struct xmemstream mem;
201+ xopen_memstream (&mem);
202+ for (int i = 0; i < 200; ++i)
203+ fprintf (mem.out, "address: STREAM/TCP 192.0.2.%d 80\n", i + 1);
204+ xfclose_memstream (&mem);
205+ expected_result = mem.buffer;
206+ }
207+
208+ check_addrinfo ("example.com", ai, ret, expected_result);
209+
210+ free (expected_result);
211+ freeaddrinfo (ai);
212+ }
213+
214+ resolv_test_end (obj);
215+ return 0;
216+}
217+
218+#include <support/test-driver.c>
219--
2202.39.2
221