Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:42.3:Staging:E
libcares2
c-ares-CVE-2016-5180.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File c-ares-CVE-2016-5180.patch of Package libcares2
From 65c71be1cbe587f290432bef2f669ee6cb8ac137 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg <daniel@haxx.se> Date: Fri, 23 Sep 2016 14:44:11 +0200 Subject: [PATCH] ares_create_query: avoid single-byte buffer overwrite ... when the name ends with an escaped dot. CVE-2016-5180 Bug: https://c-ares.haxx.se/adv_20160929.html --- ares_mkquery.c | 84 +++++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 45 deletions(-) Index: c-ares-1.9.1/ares_mkquery.c =================================================================== --- c-ares-1.9.1.orig/ares_mkquery.c +++ c-ares-1.9.1/ares_mkquery.c @@ -86,56 +86,28 @@ */ int ares_mkquery(const char *name, int dnsclass, int type, unsigned short id, - int rd, unsigned char **buf, int *buflen) + int rd, unsigned char **bufp, int *buflenp) { int len; unsigned char *q; const char *p; + size_t buflen; + unsigned char *buf; /* Set our results early, in case we bail out early with an error. */ - *buflen = 0; - *buf = NULL; - - /* Compute the length of the encoded name so we can check buflen. - * Start counting at 1 for the zero-length label at the end. */ - len = 1; - for (p = name; *p; p++) - { - if (*p == '\\' && *(p + 1) != 0) - p++; - len++; - } - /* If there are n periods in the name, there are n + 1 labels, and - * thus n + 1 length fields, unless the name is empty or ends with a - * period. So add 1 unless name is empty or ends with a period. + *buflenp = 0; + *bufp = NULL; + /* Allocate a memory area for the maximum size this packet might need. +2 + * is for the length byte and zero termination if no dots or ecscaping is + * used. */ - if (*name && *(p - 1) != '.') - len++; - - /* Immediately reject names that are longer than the maximum of 255 - * bytes that's specified in RFC 1035 ("To simplify implementations, - * the total length of a domain name (i.e., label octets and label - * length octets) is restricted to 255 octets or less."). We aren't - * doing this just to be a stickler about RFCs. For names that are - * too long, 'dnscache' closes its TCP connection to us immediately - * (when using TCP) and ignores the request when using UDP, and - * BIND's named returns ServFail (TCP or UDP). Sending a request - * that we know will cause 'dnscache' to close the TCP connection is - * painful, since that makes any other outstanding requests on that - * connection fail. And sending a UDP request that we know - * 'dnscache' will ignore is bad because resources will be tied up - * until we time-out the request. - */ - if (len > MAXCDNAME) - return ARES_EBADNAME; - - *buflen = len + HFIXEDSZ + QFIXEDSZ; - *buf = malloc(*buflen); - if (!*buf) - return ARES_ENOMEM; + len = strlen(name) + 2 + HFIXEDSZ + QFIXEDSZ; + buf = malloc(len); + if (!buf) + return ARES_ENOMEM; /* Set up the header. */ - q = *buf; + q = buf; memset(q, 0, HFIXEDSZ); DNS_HEADER_SET_QID(q, id); DNS_HEADER_SET_OPCODE(q, QUERY); @@ -155,8 +127,10 @@ int ares_mkquery(const char *name, int d q += HFIXEDSZ; while (*name) { - if (*name == '.') + if (*name == '.') { + free (buf); return ARES_EBADNAME; + } /* Count the number of bytes in this label. */ len = 0; @@ -166,8 +140,10 @@ int ares_mkquery(const char *name, int d p++; len++; } - if (len > MAXLABEL) + if (len > MAXLABEL) { + free (buf); return ARES_EBADNAME; + } /* Encode the length and copy the data. */ *q++ = (unsigned char)len; @@ -191,5 +167,21 @@ int ares_mkquery(const char *name, int d DNS_QUESTION_SET_TYPE(q, type); DNS_QUESTION_SET_CLASS(q, dnsclass); + q += QFIXEDSZ; + buflen = (q - buf); + + /* Reject names that are longer than the maximum of 255 bytes that's + * specified in RFC 1035 ("To simplify implementations, the total length of + * a domain name (i.e., label octets and label length octets) is restricted + * to 255 octets or less."). */ + if (buflen > (MAXCDNAME + HFIXEDSZ + QFIXEDSZ)) { + free (buf); + return ARES_EBADNAME; + } + + /* we know this fits in an int at this point */ + *buflenp = (int) buflen; + *bufp = buf; + return ARES_SUCCESS; }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor