Resolver: protection from duplicate responses.

If we already had CNAME in resolver node (i.e. rn->cnlen and rn->u.cname
set), and got additional response with A record, it resulted in rn->cnlen
set and rn->u.cname overwritten by rn->u.addr (or rn->u.addrs), causing
segmentation fault later in ngx_resolver_free_node() on an attempt to free
overwritten rn->u.cname.  The opposite (i.e. CNAME got after A) might cause
similar problems as well.
This commit is contained in:
Maxim Dounin 2012-05-14 09:13:45 +00:00
parent 0e3b423dc6
commit 7d863c0181

View File

@ -513,8 +513,10 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
/* lock alloc mutex */
ngx_resolver_free_locked(r, rn->query);
rn->query = NULL;
if (rn->query) {
ngx_resolver_free_locked(r, rn->query);
rn->query = NULL;
}
if (rn->cnlen) {
ngx_resolver_free_locked(r, rn->u.cname);
@ -1409,6 +1411,9 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
ngx_resolver_free(r, addrs);
}
ngx_resolver_free(r, rn->query);
rn->query = NULL;
return;
} else if (cname) {
@ -1441,6 +1446,9 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
(void) ngx_resolve_name_locked(r, ctx);
}
ngx_resolver_free(r, rn->query);
rn->query = NULL;
return;
}