Change-Id: I4ebee5ba22c7fbec36ec9f0d31b75abd288ab5d1
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/4302
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Vinay Kulkarni <kulkarniv@vmware.com>
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,310 @@ |
| 0 |
+From 20f534e0abd81149c71cef082c8c058bb9d953af Mon Sep 17 00:00:00 2001 |
|
| 1 |
+From: Florian Weimer <fweimer@redhat.com> |
|
| 2 |
+Date: Sat, 31 Dec 2016 20:22:09 +0100 |
|
| 3 |
+Subject: [PATCH] CVE-2015-5180: resolv: Fix crash with internal QTYPE [BZ |
|
| 4 |
+ #18784] |
|
| 5 |
+ |
|
| 6 |
+Also rename T_UNSPEC because an upcoming public header file |
|
| 7 |
+update will use that name. |
|
| 8 |
+ |
|
| 9 |
+(cherry picked from commit fc82b0a2dfe7dbd35671c10510a8da1043d746a5) |
|
| 10 |
+(cherry picked from commit b3b37f1a5559a7620e31c8053ed1b44f798f2b6d) |
|
| 11 |
+--- |
|
| 12 |
+ include/arpa/nameser_compat.h | 6 +- |
|
| 13 |
+ resolv/Makefile | 5 ++ |
|
| 14 |
+ resolv/nss_dns/dns-host.c | 2 +- |
|
| 15 |
+ resolv/res_mkquery.c | 4 + |
|
| 16 |
+ resolv/res_query.c | 6 +- |
|
| 17 |
+ resolv/tst-resolv-qtypes.c | 185 ++++++++++++++++++++++++++++++++++++++++++ |
|
| 18 |
+ 6 files changed, 201 insertions(+), 7 deletions(-) |
|
| 19 |
+ create mode 100644 resolv/tst-resolv-qtypes.c |
|
| 20 |
+ |
|
| 21 |
+diff --git a/include/arpa/nameser_compat.h b/include/arpa/nameser_compat.h |
|
| 22 |
+index 2e735ed..7c0deed 100644 |
|
| 23 |
+--- a/include/arpa/nameser_compat.h |
|
| 24 |
+@@ -1,8 +1,8 @@ |
|
| 25 |
+ #ifndef _ARPA_NAMESER_COMPAT_ |
|
| 26 |
+ #include <resolv/arpa/nameser_compat.h> |
|
| 27 |
+ |
|
| 28 |
+-/* Picksome unused number to represent lookups of IPv4 and IPv6 (i.e., |
|
| 29 |
+- T_A and T_AAAA). */ |
|
| 30 |
+-#define T_UNSPEC 62321 |
|
| 31 |
++/* The number is outside the 16-bit RR type range and is used |
|
| 32 |
++ internally by the implementation. */ |
|
| 33 |
++#define T_QUERY_A_AND_AAAA 439963904 |
|
| 34 |
+ |
|
| 35 |
+ #endif |
|
| 36 |
+diff --git a/resolv/Makefile b/resolv/Makefile |
|
| 37 |
+index 8be41d3..a4c86b9 100644 |
|
| 38 |
+--- a/resolv/Makefile |
|
| 39 |
+@@ -40,6 +40,9 @@ ifeq ($(have-thread-library),yes) |
|
| 40 |
+ extra-libs += libanl |
|
| 41 |
+ routines += gai_sigqueue |
|
| 42 |
+ tests += tst-res_hconf_reorder |
|
| 43 |
++ |
|
| 44 |
++# This test sends millions of packets and is rather slow. |
|
| 45 |
++xtests += tst-resolv-qtypes |
|
| 46 |
+ endif |
|
| 47 |
+ extra-libs-others = $(extra-libs) |
|
| 48 |
+ libresolv-routines := gethnamaddr res_comp res_debug \ |
|
| 49 |
+@@ -117,3 +120,5 @@ tst-leaks2-ENV = MALLOC_TRACE=$(objpfx)tst-leaks2.mtrace |
|
| 50 |
+ $(objpfx)mtrace-tst-leaks2.out: $(objpfx)tst-leaks2.out |
|
| 51 |
+ $(common-objpfx)malloc/mtrace $(objpfx)tst-leaks2.mtrace > $@; \ |
|
| 52 |
+ $(evaluate-test) |
|
| 53 |
++ |
|
| 54 |
++$(objpfx)tst-resolv-qtypes: $(objpfx)libresolv.so $(shared-thread-library) |
|
| 55 |
+diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c |
|
| 56 |
+index 5f9e357..d16fa4b 100644 |
|
| 57 |
+--- a/resolv/nss_dns/dns-host.c |
|
| 58 |
+@@ -323,7 +323,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, |
|
| 59 |
+ |
|
| 60 |
+ int olderr = errno; |
|
| 61 |
+ enum nss_status status; |
|
| 62 |
+- int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC, |
|
| 63 |
++ int n = __libc_res_nsearch (&_res, name, C_IN, T_QUERY_A_AND_AAAA, |
|
| 64 |
+ host_buffer.buf->buf, 2048, &host_buffer.ptr, |
|
| 65 |
+ &ans2p, &nans2p, &resplen2, &ans2p_malloced); |
|
| 66 |
+ if (n >= 0) |
|
| 67 |
+diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c |
|
| 68 |
+index 12f9730..d80b531 100644 |
|
| 69 |
+--- a/resolv/res_mkquery.c |
|
| 70 |
+@@ -103,6 +103,10 @@ res_nmkquery(res_state statp, |
|
| 71 |
+ int n; |
|
| 72 |
+ u_char *dnptrs[20], **dpp, **lastdnptr; |
|
| 73 |
+ |
|
| 74 |
++ if (class < 0 || class > 65535 |
|
| 75 |
++ || type < 0 || type > 65535) |
|
| 76 |
++ return -1; |
|
| 77 |
++ |
|
| 78 |
+ #ifdef DEBUG |
|
| 79 |
+ if (statp->options & RES_DEBUG) |
|
| 80 |
+ printf(";; res_nmkquery(%s, %s, %s, %s)\n",
|
|
| 81 |
+diff --git a/resolv/res_query.c b/resolv/res_query.c |
|
| 82 |
+index 944d1a9..07dc6f6 100644 |
|
| 83 |
+--- a/resolv/res_query.c |
|
| 84 |
+@@ -122,7 +122,7 @@ __libc_res_nquery(res_state statp, |
|
| 85 |
+ int n, use_malloc = 0; |
|
| 86 |
+ u_int oflags = statp->_flags; |
|
| 87 |
+ |
|
| 88 |
+- size_t bufsize = (type == T_UNSPEC ? 2 : 1) * QUERYSIZE; |
|
| 89 |
++ size_t bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * QUERYSIZE; |
|
| 90 |
+ u_char *buf = alloca (bufsize); |
|
| 91 |
+ u_char *query1 = buf; |
|
| 92 |
+ int nquery1 = -1; |
|
| 93 |
+@@ -137,7 +137,7 @@ __libc_res_nquery(res_state statp, |
|
| 94 |
+ printf(";; res_query(%s, %d, %d)\n", name, class, type);
|
|
| 95 |
+ #endif |
|
| 96 |
+ |
|
| 97 |
+- if (type == T_UNSPEC) |
|
| 98 |
++ if (type == T_QUERY_A_AND_AAAA) |
|
| 99 |
+ {
|
|
| 100 |
+ n = res_nmkquery(statp, QUERY, name, class, T_A, NULL, 0, NULL, |
|
| 101 |
+ query1, bufsize); |
|
| 102 |
+@@ -190,7 +190,7 @@ __libc_res_nquery(res_state statp, |
|
| 103 |
+ if (__builtin_expect (n <= 0, 0) && !use_malloc) {
|
|
| 104 |
+ /* Retry just in case res_nmkquery failed because of too |
|
| 105 |
+ short buffer. Shouldn't happen. */ |
|
| 106 |
+- bufsize = (type == T_UNSPEC ? 2 : 1) * MAXPACKET; |
|
| 107 |
++ bufsize = (type == T_QUERY_A_AND_AAAA ? 2 : 1) * MAXPACKET; |
|
| 108 |
+ buf = malloc (bufsize); |
|
| 109 |
+ if (buf != NULL) {
|
|
| 110 |
+ query1 = buf; |
|
| 111 |
+diff --git a/resolv/tst-resolv-qtypes.c b/resolv/tst-resolv-qtypes.c |
|
| 112 |
+new file mode 100644 |
|
| 113 |
+index 0000000..b3e60c6 |
|
| 114 |
+--- /dev/null |
|
| 115 |
+@@ -0,0 +1,185 @@ |
|
| 116 |
++/* Exercise low-level query functions with different QTYPEs. |
|
| 117 |
++ Copyright (C) 2016 Free Software Foundation, Inc. |
|
| 118 |
++ This file is part of the GNU C Library. |
|
| 119 |
++ |
|
| 120 |
++ The GNU C Library is free software; you can redistribute it and/or |
|
| 121 |
++ modify it under the terms of the GNU Lesser General Public |
|
| 122 |
++ License as published by the Free Software Foundation; either |
|
| 123 |
++ version 2.1 of the License, or (at your option) any later version. |
|
| 124 |
++ |
|
| 125 |
++ The GNU C Library is distributed in the hope that it will be useful, |
|
| 126 |
++ but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 127 |
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
| 128 |
++ Lesser General Public License for more details. |
|
| 129 |
++ |
|
| 130 |
++ You should have received a copy of the GNU Lesser General Public |
|
| 131 |
++ License along with the GNU C Library; if not, see |
|
| 132 |
++ <http://www.gnu.org/licenses/>. */ |
|
| 133 |
++ |
|
| 134 |
++#include <resolv.h> |
|
| 135 |
++#include <string.h> |
|
| 136 |
++#include <support/check.h> |
|
| 137 |
++#include <support/check_nss.h> |
|
| 138 |
++#include <support/resolv_test.h> |
|
| 139 |
++#include <support/support.h> |
|
| 140 |
++#include <support/test-driver.h> |
|
| 141 |
++#include <support/xmemstream.h> |
|
| 142 |
++ |
|
| 143 |
++/* If ture, the response function will send the actual response packet |
|
| 144 |
++ over TCP instead of UDP. */ |
|
| 145 |
++static volatile bool force_tcp; |
|
| 146 |
++ |
|
| 147 |
++/* Send back a fake resource record matching the QTYPE. */ |
|
| 148 |
++static void |
|
| 149 |
++response (const struct resolv_response_context *ctx, |
|
| 150 |
++ struct resolv_response_builder *b, |
|
| 151 |
++ const char *qname, uint16_t qclass, uint16_t qtype) |
|
| 152 |
++{
|
|
| 153 |
++ if (force_tcp && ctx->tcp) |
|
| 154 |
++ {
|
|
| 155 |
++ resolv_response_init (b, (struct resolv_response_flags) { .tc = 1 });
|
|
| 156 |
++ resolv_response_add_question (b, qname, qclass, qtype); |
|
| 157 |
++ return; |
|
| 158 |
++ } |
|
| 159 |
++ |
|
| 160 |
++ resolv_response_init (b, (struct resolv_response_flags) { });
|
|
| 161 |
++ resolv_response_add_question (b, qname, qclass, qtype); |
|
| 162 |
++ resolv_response_section (b, ns_s_an); |
|
| 163 |
++ resolv_response_open_record (b, qname, qclass, qtype, 0); |
|
| 164 |
++ resolv_response_add_data (b, &qtype, sizeof (qtype)); |
|
| 165 |
++ resolv_response_close_record (b); |
|
| 166 |
++} |
|
| 167 |
++ |
|
| 168 |
++static const const char *domain = "www.example.com"; |
|
| 169 |
++ |
|
| 170 |
++static int |
|
| 171 |
++wrap_res_query (int type, unsigned char *answer, int answer_length) |
|
| 172 |
++{
|
|
| 173 |
++ return res_query (domain, C_IN, type, answer, answer_length); |
|
| 174 |
++} |
|
| 175 |
++ |
|
| 176 |
++static int |
|
| 177 |
++wrap_res_search (int type, unsigned char *answer, int answer_length) |
|
| 178 |
++{
|
|
| 179 |
++ return res_query (domain, C_IN, type, answer, answer_length); |
|
| 180 |
++} |
|
| 181 |
++ |
|
| 182 |
++static int |
|
| 183 |
++wrap_res_querydomain (int type, unsigned char *answer, int answer_length) |
|
| 184 |
++{
|
|
| 185 |
++ return res_querydomain ("www", "example.com", C_IN, type,
|
|
| 186 |
++ answer, answer_length); |
|
| 187 |
++} |
|
| 188 |
++ |
|
| 189 |
++static int |
|
| 190 |
++wrap_res_send (int type, unsigned char *answer, int answer_length) |
|
| 191 |
++{
|
|
| 192 |
++ unsigned char buf[512]; |
|
| 193 |
++ int ret = res_mkquery (QUERY, domain, C_IN, type, |
|
| 194 |
++ (const unsigned char *) "", 0, NULL, |
|
| 195 |
++ buf, sizeof (buf)); |
|
| 196 |
++ if (type < 0 || type >= 65536) |
|
| 197 |
++ {
|
|
| 198 |
++ /* res_mkquery fails for out-of-range record types. */ |
|
| 199 |
++ TEST_VERIFY_EXIT (ret == -1); |
|
| 200 |
++ return -1; |
|
| 201 |
++ } |
|
| 202 |
++ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */ |
|
| 203 |
++ return res_send (buf, ret, answer, answer_length); |
|
| 204 |
++} |
|
| 205 |
++ |
|
| 206 |
++static int |
|
| 207 |
++wrap_res_nquery (int type, unsigned char *answer, int answer_length) |
|
| 208 |
++{
|
|
| 209 |
++ return res_nquery (&_res, domain, C_IN, type, answer, answer_length); |
|
| 210 |
++} |
|
| 211 |
++ |
|
| 212 |
++static int |
|
| 213 |
++wrap_res_nsearch (int type, unsigned char *answer, int answer_length) |
|
| 214 |
++{
|
|
| 215 |
++ return res_nquery (&_res, domain, C_IN, type, answer, answer_length); |
|
| 216 |
++} |
|
| 217 |
++ |
|
| 218 |
++static int |
|
| 219 |
++wrap_res_nquerydomain (int type, unsigned char *answer, int answer_length) |
|
| 220 |
++{
|
|
| 221 |
++ return res_nquerydomain (&_res, "www", "example.com", C_IN, type, |
|
| 222 |
++ answer, answer_length); |
|
| 223 |
++} |
|
| 224 |
++ |
|
| 225 |
++static int |
|
| 226 |
++wrap_res_nsend (int type, unsigned char *answer, int answer_length) |
|
| 227 |
++{
|
|
| 228 |
++ unsigned char buf[512]; |
|
| 229 |
++ int ret = res_nmkquery (&_res, QUERY, domain, C_IN, type, |
|
| 230 |
++ (const unsigned char *) "", 0, NULL, |
|
| 231 |
++ buf, sizeof (buf)); |
|
| 232 |
++ if (type < 0 || type >= 65536) |
|
| 233 |
++ {
|
|
| 234 |
++ /* res_mkquery fails for out-of-range record types. */ |
|
| 235 |
++ TEST_VERIFY_EXIT (ret == -1); |
|
| 236 |
++ return -1; |
|
| 237 |
++ } |
|
| 238 |
++ TEST_VERIFY_EXIT (ret > 12); /* DNS header length. */ |
|
| 239 |
++ return res_nsend (&_res, buf, ret, answer, answer_length); |
|
| 240 |
++} |
|
| 241 |
++ |
|
| 242 |
++static void |
|
| 243 |
++test_function (const char *fname, |
|
| 244 |
++ int (*func) (int type, |
|
| 245 |
++ unsigned char *answer, int answer_length)) |
|
| 246 |
++{
|
|
| 247 |
++ unsigned char buf[512]; |
|
| 248 |
++ for (int tcp = 0; tcp < 2; ++tcp) |
|
| 249 |
++ {
|
|
| 250 |
++ force_tcp = tcp; |
|
| 251 |
++ for (unsigned int type = 1; type <= 65535; ++type) |
|
| 252 |
++ {
|
|
| 253 |
++ if (test_verbose) |
|
| 254 |
++ printf ("info: sending QTYPE %d with %s (tcp=%d)\n",
|
|
| 255 |
++ type, fname, tcp); |
|
| 256 |
++ int ret = func (type, buf, sizeof (buf)); |
|
| 257 |
++ if (ret != 47) |
|
| 258 |
++ FAIL_EXIT1 ("%s tcp=%d qtype=%d return value %d",
|
|
| 259 |
++ fname,tcp, type, ret); |
|
| 260 |
++ /* One question, one answer record. */ |
|
| 261 |
++ TEST_VERIFY (memcmp (buf + 4, "\0\1\0\1\0\0\0\0", 8) == 0); |
|
| 262 |
++ /* Question section. */ |
|
| 263 |
++ static const char qname[] = "\3www\7example\3com"; |
|
| 264 |
++ size_t qname_length = sizeof (qname); |
|
| 265 |
++ TEST_VERIFY (memcmp (buf + 12, qname, qname_length) == 0); |
|
| 266 |
++ /* RDATA part of answer. */ |
|
| 267 |
++ uint16_t type16 = type; |
|
| 268 |
++ TEST_VERIFY (memcmp (buf + ret - 2, &type16, sizeof (type16)) == 0); |
|
| 269 |
++ } |
|
| 270 |
++ } |
|
| 271 |
++ |
|
| 272 |
++ TEST_VERIFY (func (-1, buf, sizeof (buf) == -1)); |
|
| 273 |
++ TEST_VERIFY (func (65536, buf, sizeof (buf) == -1)); |
|
| 274 |
++} |
|
| 275 |
++ |
|
| 276 |
++static int |
|
| 277 |
++do_test (void) |
|
| 278 |
++{
|
|
| 279 |
++ struct resolv_redirect_config config = |
|
| 280 |
++ {
|
|
| 281 |
++ .response_callback = response, |
|
| 282 |
++ }; |
|
| 283 |
++ struct resolv_test *obj = resolv_test_start (config); |
|
| 284 |
++ |
|
| 285 |
++ test_function ("res_query", &wrap_res_query);
|
|
| 286 |
++ test_function ("res_search", &wrap_res_search);
|
|
| 287 |
++ test_function ("res_querydomain", &wrap_res_querydomain);
|
|
| 288 |
++ test_function ("res_send", &wrap_res_send);
|
|
| 289 |
++ |
|
| 290 |
++ test_function ("res_nquery", &wrap_res_nquery);
|
|
| 291 |
++ test_function ("res_nsearch", &wrap_res_nsearch);
|
|
| 292 |
++ test_function ("res_nquerydomain", &wrap_res_nquerydomain);
|
|
| 293 |
++ test_function ("res_nsend", &wrap_res_nsend);
|
|
| 294 |
++ |
|
| 295 |
++ resolv_test_end (obj); |
|
| 296 |
++ return 0; |
|
| 297 |
++} |
|
| 298 |
++ |
|
| 299 |
++#define TIMEOUT 300 |
|
| 300 |
++#include <support/test-driver.c> |
|
| 301 |
+-- |
|
| 302 |
+2.9.3 |
|
| 303 |
+ |
| ... | ... |
@@ -6,7 +6,7 @@ |
| 6 | 6 |
Summary: Main C library |
| 7 | 7 |
Name: glibc |
| 8 | 8 |
Version: 2.22 |
| 9 |
-Release: 15%{?dist}
|
|
| 9 |
+Release: 16%{?dist}
|
|
| 10 | 10 |
License: LGPLv2+ |
| 11 | 11 |
URL: http://www.gnu.org/software/libc |
| 12 | 12 |
Group: Applications/System |
| ... | ... |
@@ -41,6 +41,8 @@ Patch15: glibc-fix-CVE-2017-1000366.patch |
| 41 | 41 |
Patch16: glibc-fix-CVE-2017-12133.patch |
| 42 | 42 |
Patch17: glibc-fix-CVE-2017-15670.patch |
| 43 | 43 |
Patch18: glibc-fix-CVE-2017-15804.patch |
| 44 |
+#https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=patch;h=20f534e0abd81149c71cef082c8c058bb9d953af |
|
| 45 |
+Patch19: glibc-fix-CVE-2015-5180.patch |
|
| 44 | 46 |
Provides: rtld(GNU_HASH) |
| 45 | 47 |
Requires: filesystem |
| 46 | 48 |
%description |
| ... | ... |
@@ -85,6 +87,7 @@ sed -i 's/\\$$(pwd)/`pwd`/' timezone/Makefile |
| 85 | 85 |
%patch16 -p1 |
| 86 | 86 |
%patch17 -p1 |
| 87 | 87 |
%patch18 -p1 |
| 88 |
+%patch19 -p1 |
|
| 88 | 89 |
install -vdm 755 %{_builddir}/%{name}-build
|
| 89 | 90 |
# do not try to explicitly provide GLIBC_PRIVATE versioned libraries |
| 90 | 91 |
%define __find_provides %{_builddir}/%{name}-%{version}/find_provides.sh
|
| ... | ... |
@@ -210,8 +213,9 @@ popd |
| 210 | 210 |
%defattr(-,root,root) |
| 211 | 211 |
%{_datarootdir}/locale/locale.alias
|
| 212 | 212 |
|
| 213 |
- |
|
| 214 | 213 |
%changelog |
| 214 |
+* Tue Nov 14 2017 Xiaolin Li <xiaolinl@vmware.com> 2.22-16 |
|
| 215 |
+- Fix CVE-2015-5180 |
|
| 215 | 216 |
* Wed Oct 25 2017 Xiaolin Li <xiaolinl@vmware.com> 2.22-15 |
| 216 | 217 |
- Fix CVE-2017-15670, CVE-2017-15804 |
| 217 | 218 |
* Thu Oct 19 2017 Xiaolin Li <xiaolinl@vmware.com> 2.22-14 |