glibc/glibc-rh168253-res_mkquery-gnu-style.patch
Florian Weimer 8597553f96 Rebase DNS stub resolver to the glibc 2.26 version
- Support an arbitrary number of search domains (#168253)
- Detect and apply /etc/resolv.conf changes in libresolv (#1374239)
- CVE-2015-5180: DNS stub resolver crash with crafted record type (#1251403)
2017-10-11 14:41:27 +02:00

324 lines
9.7 KiB
Diff

commit 74084febc4b668ca2258d88cade6fa5e28364ac6
Author: Florian Weimer <fweimer@redhat.com>
Date: Fri Jun 30 11:31:12 2017 +0200
resolv: Reformat resolv/res_mkquery.c to GNU style
diff --git a/resolv/res_mkquery.c b/resolv/res_mkquery.c
index 2e3aa39cf088adf9..a601b6988545a149 100644
--- a/resolv/res_mkquery.c
+++ b/resolv/res_mkquery.c
@@ -97,172 +97,168 @@
# define RANDOM_BITS(Var) { uint64_t v64; HP_TIMING_NOW (v64); Var = v64; }
#endif
-/*
- * Form all types of queries.
- * Returns the size of the result or -1.
- */
+/* Form all types of queries. Returns the size of the result or -1 on
+ error.
+
+ STATP points to an initialized resolver state. OP is the opcode of
+ the query. DNAME is the domain. CLASS and TYPE are the DNS query
+ class and type. DATA can be NULL; otherwise, it is a pointer to a
+ domain name which is included in the generated packet (if op ==
+ NS_NOTIFY_OP). BUF must point to the out buffer of BUFLEN bytes.
+
+ DATALEN and NEWRR_IN are currently ignored. */
int
-res_nmkquery(res_state statp,
- int op, /* opcode of query */
- const char *dname, /* domain name */
- int class, int type, /* class and type of query */
- const u_char *data, /* resource record data */
- int datalen, /* length of data */
- const u_char *newrr_in, /* new rr for modify or append */
- u_char *buf, /* buffer to put query */
- int buflen) /* size of buffer */
+res_nmkquery (res_state statp, int op, const char *dname,
+ int class, int type,
+ const unsigned char *data, int datalen,
+ const unsigned char *newrr_in,
+ unsigned char *buf, int buflen)
{
- HEADER *hp;
- u_char *cp;
- int n;
- u_char *dnptrs[20], **dpp, **lastdnptr;
+ HEADER *hp;
+ unsigned char *cp;
+ int n;
+ unsigned char *dnptrs[20], **dpp, **lastdnptr;
- if (class < 0 || class > 65535
- || type < 0 || type > 65535)
- return -1;
+ if (class < 0 || class > 65535 || type < 0 || type > 65535)
+ return -1;
- /*
- * Initialize header fields.
- */
- if ((buf == NULL) || (buflen < HFIXEDSZ))
- return (-1);
- memset(buf, 0, HFIXEDSZ);
- hp = (HEADER *) buf;
- /* We randomize the IDs every time. The old code just
- incremented by one after the initial randomization which
- still predictable if the application does multiple
- requests. */
- int randombits;
- do
- {
+ /* Initialize header fields. */
+ if ((buf == NULL) || (buflen < HFIXEDSZ))
+ return -1;
+ memset (buf, 0, HFIXEDSZ);
+ hp = (HEADER *) buf;
+ /* We randomize the IDs every time. The old code just incremented
+ by one after the initial randomization which still predictable if
+ the application does multiple requests. */
+ int randombits;
+ do
+ {
#ifdef RANDOM_BITS
- RANDOM_BITS (randombits);
+ RANDOM_BITS (randombits);
#else
- struct timeval tv;
- __gettimeofday (&tv, NULL);
- randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
+ struct timeval tv;
+ __gettimeofday (&tv, NULL);
+ randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
#endif
- }
- while ((randombits & 0xffff) == 0);
- statp->id = (statp->id + randombits) & 0xffff;
- hp->id = statp->id;
- hp->opcode = op;
- hp->rd = (statp->options & RES_RECURSE) != 0;
- hp->rcode = NOERROR;
- cp = buf + HFIXEDSZ;
- buflen -= HFIXEDSZ;
- dpp = dnptrs;
- *dpp++ = buf;
- *dpp++ = NULL;
- lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
- /*
- * perform opcode specific processing
- */
- switch (op) {
- case NS_NOTIFY_OP:
- if ((buflen -= QFIXEDSZ + (data == NULL ? 0 : RRFIXEDSZ)) < 0)
- return (-1);
- goto compose;
+ }
+ while ((randombits & 0xffff) == 0);
+
+ statp->id = (statp->id + randombits) & 0xffff;
+ hp->id = statp->id;
+ hp->opcode = op;
+ hp->rd = (statp->options & RES_RECURSE) != 0;
+ hp->rcode = NOERROR;
+ cp = buf + HFIXEDSZ;
+ buflen -= HFIXEDSZ;
+ dpp = dnptrs;
+ *dpp++ = buf;
+ *dpp++ = NULL;
+ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
- case QUERY:
- if ((buflen -= QFIXEDSZ) < 0)
- return (-1);
- compose:
- n = ns_name_compress(dname, cp, buflen,
- (const u_char **) dnptrs,
- (const u_char **) lastdnptr);
- if (n < 0)
- return (-1);
- cp += n;
- buflen -= n;
- NS_PUT16 (type, cp);
- NS_PUT16 (class, cp);
- hp->qdcount = htons(1);
- if (op == QUERY || data == NULL)
- break;
- /*
- * Make an additional record for completion domain.
- */
- n = ns_name_compress((char *)data, cp, buflen,
- (const u_char **) dnptrs,
- (const u_char **) lastdnptr);
- if (__glibc_unlikely (n < 0))
- return (-1);
- cp += n;
- buflen -= n;
- NS_PUT16 (T_NULL, cp);
- NS_PUT16 (class, cp);
- NS_PUT32 (0, cp);
- NS_PUT16 (0, cp);
- hp->arcount = htons(1);
- break;
+ /* Perform opcode specific processing. */
+ switch (op)
+ {
+ case NS_NOTIFY_OP:
+ if ((buflen -= QFIXEDSZ + (data == NULL ? 0 : RRFIXEDSZ)) < 0)
+ return -1;
+ goto compose;
- default:
- return (-1);
- }
- return (cp - buf);
+ case QUERY:
+ if ((buflen -= QFIXEDSZ) < 0)
+ return -1;
+ compose:
+ n = ns_name_compress (dname, cp, buflen,
+ (const unsigned char **) dnptrs,
+ (const unsigned char **) lastdnptr);
+ if (n < 0)
+ return -1;
+ cp += n;
+ buflen -= n;
+ NS_PUT16 (type, cp);
+ NS_PUT16 (class, cp);
+ hp->qdcount = htons (1);
+ if (op == QUERY || data == NULL)
+ break;
+
+ /* Make an additional record for completion domain. */
+ n = ns_name_compress ((char *)data, cp, buflen,
+ (const unsigned char **) dnptrs,
+ (const unsigned char **) lastdnptr);
+ if (__glibc_unlikely (n < 0))
+ return -1;
+ cp += n;
+ buflen -= n;
+ NS_PUT16 (T_NULL, cp);
+ NS_PUT16 (class, cp);
+ NS_PUT32 (0, cp);
+ NS_PUT16 (0, cp);
+ hp->arcount = htons (1);
+ break;
+
+ default:
+ return -1;
+ }
+ return cp - buf;
}
libresolv_hidden_def (res_nmkquery)
+/* Create an OPT resource record. Return the length of the final
+ packet, or -1 on error.
-/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
-#ifndef T_OPT
-#define T_OPT 41
-#endif
-
+ STATP must be an initialized resolver state. N0 is the current
+ number of bytes of the packet (already written to BUF by the
+ aller). BUF is the packet being constructed. The array it
+ pointers to must be BUFLEN bytes long. ANSLEN is the advertised
+ EDNS buffer size (to be included in the OPT resource record). */
int
-__res_nopt(res_state statp,
- int n0, /* current offset in buffer */
- u_char *buf, /* buffer to put query */
- int buflen, /* size of buffer */
- int anslen) /* UDP answer buffer size */
+__res_nopt (res_state statp, int n0, unsigned char *buf, int buflen,
+ int anslen)
{
- u_int16_t flags = 0;
-
- HEADER *hp = (HEADER *) buf;
- u_char *cp = buf + n0;
- u_char *ep = buf + buflen;
+ uint16_t flags = 0;
+ HEADER *hp = (HEADER *) buf;
+ unsigned char *cp = buf + n0;
+ unsigned char *ep = buf + buflen;
- if ((ep - cp) < 1 + RRFIXEDSZ)
- return -1;
+ if ((ep - cp) < 1 + RRFIXEDSZ)
+ return -1;
- *cp++ = 0; /* "." */
+ /* Add the root label. */
+ *cp++ = 0;
- NS_PUT16(T_OPT, cp); /* TYPE */
+ NS_PUT16 (T_OPT, cp); /* Record type. */
- /* Lowering the advertised buffer size based on the actual
- answer buffer size is desirable because the server will
- minimize the reply to fit into the UDP packet (and A
- non-minimal response might not fit the buffer).
+ /* Lowering the advertised buffer size based on the actual
+ answer buffer size is desirable because the server will
+ minimize the reply to fit into the UDP packet (and A
+ non-minimal response might not fit the buffer).
- The RESOLV_EDNS_BUFFER_SIZE limit could still result in TCP
- fallback and a non-minimal response which has to be
- hard-truncated in the stub resolver, but this is price to
- pay for avoiding fragmentation. (This issue does not
- affect the nss_dns functions because they use the stub
- resolver in such a way that it allocates a properly sized
- response buffer.) */
- {
- uint16_t buffer_size;
- if (anslen < 512)
- buffer_size = 512;
- else if (anslen > RESOLV_EDNS_BUFFER_SIZE)
- buffer_size = RESOLV_EDNS_BUFFER_SIZE;
- else
- buffer_size = anslen;
- NS_PUT16 (buffer_size, cp);
- }
+ The RESOLV_EDNS_BUFFER_SIZE limit could still result in TCP
+ fallback and a non-minimal response which has to be
+ hard-truncated in the stub resolver, but this is price to
+ pay for avoiding fragmentation. (This issue does not
+ affect the nss_dns functions because they use the stub
+ resolver in such a way that it allocates a properly sized
+ response buffer.) */
+ {
+ uint16_t buffer_size;
+ if (anslen < 512)
+ buffer_size = 512;
+ else if (anslen > RESOLV_EDNS_BUFFER_SIZE)
+ buffer_size = RESOLV_EDNS_BUFFER_SIZE;
+ else
+ buffer_size = anslen;
+ NS_PUT16 (buffer_size, cp);
+ }
- *cp++ = NOERROR; /* extended RCODE */
- *cp++ = 0; /* EDNS version */
+ *cp++ = NOERROR; /* Extended RCODE. */
+ *cp++ = 0; /* EDNS version. */
- if (statp->options & RES_USE_DNSSEC) {
- flags |= NS_OPT_DNSSEC_OK;
- }
+ if (statp->options & RES_USE_DNSSEC)
+ flags |= NS_OPT_DNSSEC_OK;
- NS_PUT16(flags, cp);
- NS_PUT16(0, cp); /* RDLEN */
- hp->arcount = htons(ntohs(hp->arcount) + 1);
+ NS_PUT16 (flags, cp);
+ NS_PUT16 (0, cp); /* RDATA length (no options are preent). */
+ hp->arcount = htons (ntohs (hp->arcount) + 1);
- return cp - buf;
+ return cp - buf;
}