Merge of r4611, r4620: resolver fixes.
*) Fixed segmentation fault in ngx_resolver_create_name_query(). If name passed for resolution was { 0, NULL } (e.g. as a result of name server returning CNAME pointing to ".") pointer wrapped to (void *) -1 resulting in segmentation fault on an attempt to dereference it. Reported by Lanshun Zhou. *) 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:
parent
0af9b00afa
commit
87b4323b47
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1834,6 +1842,10 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
|
|||
p--;
|
||||
*p-- = '\0';
|
||||
|
||||
if (ctx->name.len == 0) {
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
for (s = ctx->name.data + ctx->name.len - 1; s >= ctx->name.data; s--) {
|
||||
if (*s != '.') {
|
||||
*p = *s;
|
||||
|
|
Loading…
Reference in New Issue