Mercurial > hg > nginx
view src/core/ngx_config.h @ 6351:497d0cff8ace
Resolver: fixed use-after-free memory accesses with CNAME.
When several requests were waiting for a response, then after getting
a CNAME response only the last request's context had the name updated.
Contexts of other requests had the wrong name. This name was used by
ngx_resolve_name_done() to find the node to remove the request context
from. When the name was wrong, the request could not be properly
cancelled, its context was freed but stayed linked to the node's waiting
list. This happened e.g. when the first request was aborted or timed
out before the resolving completed. When it completed, this triggered
a use-after-free memory access by calling ctx->handler of already freed
request context. The bug manifests itself by
"could not cancel <name> resolving" alerts in error_log.
When a request was responded with a CNAME, the request context kept
the pointer to the original node's rn->u.cname. If the original node
expired before the resolving timed out or completed with an error,
this would trigger a use-after-free memory access via ctx->name in
ctx->handler().
The fix is to keep ctx->name unmodified. The name from context
is no longer used by ngx_resolve_name_done(). Instead, we now keep
the pointer to resolver node to which this request is linked.
Keeping the original name intact also improves logging.
author | Roman Arutyunyan <arut@nginx.com> |
---|---|
date | Tue, 26 Jan 2016 16:46:59 +0300 |
parents | b92d5a26d55f |
children | 5805301f990f |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */ #ifndef _NGX_CONFIG_H_INCLUDED_ #define _NGX_CONFIG_H_INCLUDED_ #include <ngx_auto_headers.h> #if defined __DragonFly__ && !defined __FreeBSD__ #define __FreeBSD__ 4 #define __FreeBSD_version 480101 #endif #if (NGX_FREEBSD) #include <ngx_freebsd_config.h> #elif (NGX_LINUX) #include <ngx_linux_config.h> #elif (NGX_SOLARIS) #include <ngx_solaris_config.h> #elif (NGX_DARWIN) #include <ngx_darwin_config.h> #elif (NGX_WIN32) #include <ngx_win32_config.h> #else /* POSIX */ #include <ngx_posix_config.h> #endif #ifndef NGX_HAVE_SO_SNDLOWAT #define NGX_HAVE_SO_SNDLOWAT 1 #endif #if !(NGX_WIN32) #define ngx_signal_helper(n) SIG##n #define ngx_signal_value(n) ngx_signal_helper(n) #define ngx_random random /* TODO: #ifndef */ #define NGX_SHUTDOWN_SIGNAL QUIT #define NGX_TERMINATE_SIGNAL TERM #define NGX_NOACCEPT_SIGNAL WINCH #define NGX_RECONFIGURE_SIGNAL HUP #if (NGX_LINUXTHREADS) #define NGX_REOPEN_SIGNAL INFO #define NGX_CHANGEBIN_SIGNAL XCPU #else #define NGX_REOPEN_SIGNAL USR1 #define NGX_CHANGEBIN_SIGNAL USR2 #endif #define ngx_cdecl #define ngx_libc_cdecl #endif typedef intptr_t ngx_int_t; typedef uintptr_t ngx_uint_t; typedef intptr_t ngx_flag_t; #define NGX_INT32_LEN (sizeof("-2147483648") - 1) #define NGX_INT64_LEN (sizeof("-9223372036854775808") - 1) #if (NGX_PTR_SIZE == 4) #define NGX_INT_T_LEN NGX_INT32_LEN #define NGX_MAX_INT_T_VALUE 2147483647 #else #define NGX_INT_T_LEN NGX_INT64_LEN #define NGX_MAX_INT_T_VALUE 9223372036854775807 #endif #ifndef NGX_ALIGNMENT #define NGX_ALIGNMENT sizeof(unsigned long) /* platform word */ #endif #define ngx_align(d, a) (((d) + (a - 1)) & ~(a - 1)) #define ngx_align_ptr(p, a) \ (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1)) #define ngx_abort abort /* TODO: platform specific: array[NGX_INVALID_ARRAY_INDEX] must cause SIGSEGV */ #define NGX_INVALID_ARRAY_INDEX 0x80000000 /* TODO: auto_conf: ngx_inline inline __inline __inline__ */ #ifndef ngx_inline #define ngx_inline inline #endif #ifndef INADDR_NONE /* Solaris */ #define INADDR_NONE ((unsigned int) -1) #endif #ifdef MAXHOSTNAMELEN #define NGX_MAXHOSTNAMELEN MAXHOSTNAMELEN #else #define NGX_MAXHOSTNAMELEN 256 #endif #if ((__GNU__ == 2) && (__GNUC_MINOR__ < 8)) #define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffffLL #else #define NGX_MAX_UINT32_VALUE (uint32_t) 0xffffffff #endif #define NGX_MAX_INT32_VALUE (uint32_t) 0x7fffffff #endif /* _NGX_CONFIG_H_INCLUDED_ */