Resolver: fixed response processing.

Stricten response header checks: ensure that reserved bits are zeroes,
and that the opcode is "standard query".

Fixed the "zero-length domain name in DNS response" condition.
This commit is contained in:
Ruslan Ermilov 2013-12-06 14:30:27 +04:00
parent 23071835a3
commit f3a271f3fd

View File

@ -1022,7 +1022,6 @@ static void
ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n) ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
{ {
char *err; char *err;
size_t len;
ngx_uint_t i, times, ident, qident, flags, code, nqs, nan, ngx_uint_t i, times, ident, qident, flags, code, nqs, nan,
qtype, qclass; qtype, qclass;
ngx_queue_t *q; ngx_queue_t *q;
@ -1047,13 +1046,14 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
(response->nns_hi << 8) + response->nns_lo, (response->nns_hi << 8) + response->nns_lo,
(response->nar_hi << 8) + response->nar_lo); (response->nar_hi << 8) + response->nar_lo);
if (!(flags & 0x8000)) { /* response to a standard query */
if ((flags & 0xf870) != 0x8000) {
ngx_log_error(r->log_level, r->log, 0, ngx_log_error(r->log_level, r->log, 0,
"invalid DNS response %ui fl:%04Xui", ident, flags); "invalid DNS response %ui fl:%04Xui", ident, flags);
return; return;
} }
code = flags & 0x7f; code = flags & 0xf;
if (code == NGX_RESOLVE_FORMERR) { if (code == NGX_RESOLVE_FORMERR) {
@ -1094,15 +1094,14 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n)
goto found; goto found;
} }
len = buf[i]; i += 1 + buf[i];
i += 1 + len;
} }
goto short_response; goto short_response;
found: found:
if (i++ == 0) { if (i++ == sizeof(ngx_resolver_hdr_t)) {
err = "zero-length domain name in DNS response"; err = "zero-length domain name in DNS response";
goto done; goto done;
} }