Imported Upstream version 1.6.2

This commit is contained in:
Christos Trochalakis 2014-09-17 11:16:18 +03:00
parent 4f63260faf
commit f7b92fb086
5 changed files with 170 additions and 14 deletions

14
CHANGES
View file

@ -1,4 +1,18 @@
Changes with nginx 1.6.2 16 Sep 2014
*) Security: it was possible to reuse SSL sessions in unrelated contexts
if a shared SSL session cache or the same TLS session ticket key was
used for multiple "server" blocks (CVE-2014-3616).
Thanks to Antoine Delignat-Lavaud.
*) Bugfix: requests might hang if resolver was used and a DNS server
returned a malformed response; the bug had appeared in 1.5.8.
*) Bugfix: requests might hang if resolver was used and a timeout
occurred during a DNS request.
Changes with nginx 1.6.1 05 Aug 2014
*) Security: pipelined commands were not discarded after STARTTLS

View file

@ -1,4 +1,19 @@
Изменения в nginx 1.6.2 16.09.2014
*) Безопасность: при использовании общего для нескольких блоков server
разделяемого кэша SSL-сессий или общего ключа для шифрования TLS
session tickets было возможно повторно использовать SSL-сессию в
контексте другого блока server (CVE-2014-3616).
Спасибо Antoine Delignat-Lavaud.
*) Исправление: запросы могли зависать, если использовался resolver и
DNS-сервер возвращал некорректный ответ; ошибка появилась в 1.5.8.
*) Исправление: запросы могли зависать, если использовался resolver и в
процессе обращения к DNS-серверу происходил таймаут.
Изменения в nginx 1.6.1 05.08.2014
*) Безопасность: pipelined-команды не отбрасывались после команды

View file

@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
#define nginx_version 1006001
#define NGINX_VERSION "1.6.1"
#define nginx_version 1006002
#define NGINX_VERSION "1.6.2"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"

View file

@ -417,7 +417,7 @@ ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
/* lock name mutex */
if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
if (ctx->state == NGX_AGAIN) {
hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
@ -664,7 +664,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
}
ctx->event->handler = ngx_resolver_timeout_handler;
ctx->event->data = ctx;
ctx->event->data = rn;
ctx->event->log = r->log;
ctx->ident = -1;
@ -857,7 +857,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
}
ctx->event->handler = ngx_resolver_timeout_handler;
ctx->event->data = ctx;
ctx->event->data = rn;
ctx->event->log = r->log;
ctx->ident = -1;
@ -949,7 +949,7 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
/* lock addr mutex */
if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
if (ctx->state == NGX_AGAIN) {
switch (ctx->addr.sockaddr->sa_family) {
@ -1467,7 +1467,6 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
goto failed;
}
rn->naddrs6 = 0;
qident = (rn->query6[0] << 8) + rn->query6[1];
break;
@ -1482,7 +1481,6 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
goto failed;
}
rn->naddrs = 0;
qident = (rn->query[0] << 8) + rn->query[1];
}
@ -1507,6 +1505,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
case NGX_RESOLVE_AAAA:
rn->naddrs6 = 0;
if (rn->naddrs == (u_short) -1) {
goto next;
}
@ -1519,6 +1519,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
default: /* NGX_RESOLVE_A */
rn->naddrs = 0;
if (rn->naddrs6 == (u_short) -1) {
goto next;
}
@ -1539,6 +1541,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
case NGX_RESOLVE_AAAA:
rn->naddrs6 = 0;
if (rn->naddrs == (u_short) -1) {
rn->code = (u_char) code;
goto next;
@ -1548,6 +1552,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
default: /* NGX_RESOLVE_A */
rn->naddrs = 0;
if (rn->naddrs6 == (u_short) -1) {
rn->code = (u_char) code;
goto next;
@ -1817,6 +1823,25 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
}
}
switch (qtype) {
#if (NGX_HAVE_INET6)
case NGX_RESOLVE_AAAA:
if (rn->naddrs6 == (u_short) -1) {
rn->naddrs6 = 0;
}
break;
#endif
default: /* NGX_RESOLVE_A */
if (rn->naddrs == (u_short) -1) {
rn->naddrs = 0;
}
}
if (rn->naddrs != (u_short) -1
#if (NGX_HAVE_INET6)
&& rn->naddrs6 != (u_short) -1
@ -2766,13 +2791,21 @@ done:
static void
ngx_resolver_timeout_handler(ngx_event_t *ev)
{
ngx_resolver_ctx_t *ctx;
ngx_resolver_ctx_t *ctx, *next;
ngx_resolver_node_t *rn;
ctx = ev->data;
rn = ev->data;
ctx = rn->waiting;
rn->waiting = NULL;
ctx->state = NGX_RESOLVE_TIMEDOUT;
do {
ctx->state = NGX_RESOLVE_TIMEDOUT;
next = ctx->next;
ctx->handler(ctx);
ctx->handler(ctx);
ctx = next;
} while (ctx);
}

View file

@ -27,6 +27,8 @@ static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
ngx_err_t err, char *text);
static void ngx_ssl_clear_error(ngx_log_t *log);
static ngx_int_t ngx_ssl_session_id_context(ngx_ssl_t *ssl,
ngx_str_t *sess_ctx);
ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn,
ngx_ssl_session_t *sess);
@ -1729,13 +1731,15 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
SSL_CTX_set_timeout(ssl->ctx, (long) timeout);
if (ngx_ssl_session_id_context(ssl, sess_ctx) != NGX_OK) {
return NGX_ERROR;
}
if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
return NGX_OK;
}
SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len);
if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {
/*
@ -1792,6 +1796,96 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
}
static ngx_int_t
ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx)
{
int n, i;
X509 *cert;
X509_NAME *name;
EVP_MD_CTX md;
unsigned int len;
STACK_OF(X509_NAME) *list;
u_char buf[EVP_MAX_MD_SIZE];
/*
* Session ID context is set based on the string provided,
* the server certificate, and the client CA list.
*/
EVP_MD_CTX_init(&md);
if (EVP_DigestInit_ex(&md, EVP_sha1(), NULL) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestInit_ex() failed");
goto failed;
}
if (EVP_DigestUpdate(&md, sess_ctx->data, sess_ctx->len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestUpdate() failed");
goto failed;
}
cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"X509_digest() failed");
goto failed;
}
if (EVP_DigestUpdate(&md, buf, len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestUpdate() failed");
goto failed;
}
list = SSL_CTX_get_client_CA_list(ssl->ctx);
if (list != NULL) {
n = sk_X509_NAME_num(list);
for (i = 0; i < n; i++) {
name = sk_X509_NAME_value(list, i);
if (X509_NAME_digest(name, EVP_sha1(), buf, &len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"X509_NAME_digest() failed");
goto failed;
}
if (EVP_DigestUpdate(&md, buf, len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestUpdate() failed");
goto failed;
}
}
}
if (EVP_DigestFinal_ex(&md, buf, &len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestUpdate() failed");
goto failed;
}
EVP_MD_CTX_cleanup(&md);
if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"SSL_CTX_set_session_id_context() failed");
return NGX_ERROR;
}
return NGX_OK;
failed:
EVP_MD_CTX_cleanup(&md);
return NGX_ERROR;
}
ngx_int_t
ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
{