From 7d863c0181064b08fa6b3816522551084fd91af5 Mon Sep 17 00:00:00 2001 From: Maxim Dounin Date: Mon, 14 May 2012 09:13:45 +0000 Subject: [PATCH] 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. --- src/core/ngx_resolver.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c index ecf97d7f7..edc43dce2 100644 --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -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; }