summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-11-11 11:05:28 +0000
committerJonathan Kolb <jon@b0g.us>2009-11-11 11:05:28 +0000
commit26aac3ef382a703ffae98d36c49f1fa528894816 (patch)
tree469dbac4dac4852e54c579336d907122d4c09bb2
parentf861a4b22cf03846b613e18a15e45d2deca01d26 (diff)
downloadnginx-26aac3ef382a703ffae98d36c49f1fa528894816.tar.gz
Changes with nginx 0.8.23 11 Nov 2009v0.8.23
*) Security: now SSL/TLS renegotiation is disabled. Thanks to Maxim Dounin. *) Bugfix: listen unix domain socket did not inherit while online upgrade. *) Bugfix: the "unix:" parameter of the "set_real_ip_from" directive did not without yet another directive with any IP address. *) Bugfix: segmentation fault and infinite looping in resolver. *) Bugfix: in resolver. Thanks to Artem Bokhan.
-rw-r--r--CHANGES17
-rw-r--r--CHANGES.ru17
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_conf_file.c2
-rw-r--r--src/core/ngx_connection.c11
-rw-r--r--src/core/ngx_resolver.c11
-rw-r--r--src/event/ngx_event_openssl.c40
-rw-r--r--src/event/ngx_event_openssl.h1
-rw-r--r--src/http/modules/ngx_http_realip_module.c7
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_copy_filter_module.c2
-rw-r--r--src/http/ngx_http_file_cache.c71
-rw-r--r--src/mail/ngx_mail_smtp_handler.c2
-rw-r--r--src/os/unix/ngx_file_aio_read.c11
-rw-r--r--src/os/unix/ngx_files.c7
-rw-r--r--src/os/unix/ngx_files.h2
-rw-r--r--src/os/unix/ngx_linux_aio_read.c13
-rw-r--r--src/os/unix/ngx_posix_init.c2
-rw-r--r--src/os/unix/ngx_process_cycle.c14
19 files changed, 180 insertions, 56 deletions
diff --git a/CHANGES b/CHANGES
index 5e77be8c5..92c248097 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,21 @@
+Changes with nginx 0.8.23 11 Nov 2009
+
+ *) Security: now SSL/TLS renegotiation is disabled.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: listen unix domain socket did not inherit while online
+ upgrade.
+
+ *) Bugfix: the "unix:" parameter of the "set_real_ip_from" directive
+ did not without yet another directive with any IP address.
+
+ *) Bugfix: segmentation fault and infinite looping in resolver.
+
+ *) Bugfix: in resolver.
+ Thanks to Artem Bokhan.
+
+
Changes with nginx 0.8.22 03 Nov 2009
*) Feature: the "proxy_bind", "fastcgi_bind", and "memcached_bind"
diff --git a/CHANGES.ru b/CHANGES.ru
index 72f151a13..cda820f61 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,21 @@
+Изменения в nginx 0.8.23 11.11.2009
+
+ *) Безопасность: теперь SSL/TLS renegotiation запрещено.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: listen unix domain сокет не наследовались во время
+ обновления без перерыва.
+
+ *) Исправление: параметр "unix:" в директиве set_real_ip_from не
+ работал без ещё одной директивы с любым IP-адресом.
+
+ *) Исправление: segmentation fault и зацикливания в resolver'е.
+
+ *) Исправление: в resolver'е.
+ Спасибо Артёму Бохану.
+
+
Изменения в nginx 0.8.22 03.11.2009
*) Добавление: директивы proxy_bind, fastcgi_bind и memcached_bind.
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 406736b0d..bd80b2a1e 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 8022
-#define NGINX_VERSION "0.8.22"
+#define nginx_version 8023
+#define NGINX_VERSION "0.8.23"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c
index c58d8095f..c48d814f8 100644
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -261,7 +261,7 @@ done:
if (ngx_close_file(fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
ngx_close_file_n " %s failed",
- cf->conf_file->file.name.data);
+ filename->data);
return NGX_CONF_ERROR;
}
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index 9d064c5ac..3bd9cc676 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -117,11 +117,20 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
#if (NGX_HAVE_INET6)
case AF_INET6:
ls[i].addr_text_max_len = NGX_INET6_ADDRSTRLEN;
+ len = NGX_INET6_ADDRSTRLEN + sizeof(":65535") - 1;
+ break;
+#endif
+
+#if (NGX_HAVE_UNIX_DOMAIN)
+ case AF_UNIX:
+ ls[i].addr_text_max_len = NGX_UNIX_ADDRSTRLEN;
+ len = NGX_UNIX_ADDRSTRLEN;
break;
#endif
case AF_INET:
ls[i].addr_text_max_len = NGX_INET_ADDRSTRLEN;
+ len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1;
break;
default:
@@ -132,8 +141,6 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
continue;
}
- len = ls[i].addr_text_max_len + sizeof(":65535") - 1;
-
ls[i].addr_text.data = ngx_pnalloc(cycle->pool, len);
if (ls[i].addr_text.data == NULL) {
return NGX_ERROR;
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index 9adc2d223..48d569ea3 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -464,6 +464,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
ctx->next = rn->waiting;
rn->waiting = ctx;
+ ctx->state = NGX_AGAIN;
return NGX_AGAIN;
}
@@ -625,6 +626,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
ctx->next = rn->waiting;
rn->waiting = ctx;
+ ctx->state = NGX_AGAIN;
/* unlock addr mutex */
@@ -1752,7 +1754,8 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
query->nns_hi = 0; query->nns_lo = 0;
query->nar_hi = 0; query->nar_lo = 0;
- p += sizeof(ngx_resolver_query_t) + 1 + ctx->name.len + 1;
+ p += sizeof(ngx_resolver_query_t)
+ + ctx->name.len ? (1 + ctx->name.len + 1) : 1;
qs = (ngx_resolver_qs_t *) p;
@@ -1900,6 +1903,12 @@ done:
return NGX_OK;
}
+ if (len == -1) {
+ name->len = 0;
+ name->data = NULL;
+ return NGX_OK;
+ }
+
dst = ngx_resolver_alloc(r, len);
if (dst == NULL) {
return NGX_ERROR;
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 538861694..4a3cb82ec 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -15,6 +15,8 @@ typedef struct {
static int ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store);
+static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where,
+ int ret);
static void ngx_ssl_handshake_handler(ngx_event_t *ev);
static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
static void ngx_ssl_write_handler(ngx_event_t *wev);
@@ -175,6 +177,8 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_read_ahead(ssl->ctx, 1);
+ SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback);
+
return NGX_OK;
}
@@ -350,6 +354,22 @@ ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
}
+static void
+ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
+{
+ ngx_connection_t *c;
+
+ if (where & SSL_CB_HANDSHAKE_START) {
+ c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
+
+ if (c->ssl->handshaked) {
+ c->ssl->renegotiation = 1;
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL renegotiation");
+ }
+ }
+}
+
+
ngx_int_t
ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl)
{
@@ -587,6 +607,11 @@ ngx_ssl_handshake(ngx_connection_t *c)
c->recv_chain = ngx_ssl_recv_chain;
c->send_chain = ngx_ssl_send_chain;
+ /* initial handshake done, disable renegotiation (CVE-2009-3555) */
+ if (c->ssl->connection->s3) {
+ c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
+ }
+
return NGX_OK;
}
@@ -789,6 +814,21 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
int sslerr;
ngx_err_t err;
+ if (c->ssl->renegotiation) {
+ /*
+ * disable renegotiation (CVE-2009-3555):
+ * OpenSSL (at least up to 0.9.8l) does not handle disabled
+ * renegotiation gracefully, so drop connection here
+ */
+
+ ngx_log_error(NGX_LOG_NOTICE, c->log, 0, "SSL renegotiation disabled");
+
+ c->ssl->no_wait_shutdown = 1;
+ c->ssl->no_send_shutdown = 1;
+
+ return NGX_ERROR;
+ }
+
if (n > 0) {
if (c->ssl->saved_write_handler) {
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index deeb57f64..f3b5a2558 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -41,6 +41,7 @@ typedef struct {
ngx_event_handler_pt saved_write_handler;
unsigned handshaked:1;
+ unsigned renegotiation:1;
unsigned buffer:1;
unsigned no_wait_shutdown:1;
unsigned no_send_shutdown:1;
diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c
index 4288aaba9..7942042a3 100644
--- a/src/http/modules/ngx_http_realip_module.c
+++ b/src/http/modules/ngx_http_realip_module.c
@@ -126,7 +126,12 @@ ngx_http_realip_handler(ngx_http_request_t *r)
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module);
- if (rlcf->from == NULL) {
+ if (rlcf->from == NULL
+#if (NGX_HAVE_UNIX_DOMAIN)
+ && !rlcf->unixsock
+#endif
+ )
+ {
return NGX_DECLINED;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 2c1a90fbd..7b8e34c1f 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.8.22';
+our $VERSION = '0.8.23';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
index 3c4c2880a..a1b616a68 100644
--- a/src/http/ngx_http_copy_filter_module.c
+++ b/src/http/ngx_http_copy_filter_module.c
@@ -118,7 +118,7 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->filter_ctx = r;
#if (NGX_HAVE_FILE_AIO)
- if (clcf->aio) {
+ if (ngx_file_aio && clcf->aio) {
ctx->aio_handler = ngx_http_copy_aio_handler;
#if (NGX_HAVE_AIO_SENDFILE)
c->aio_sendfile = (clcf->aio == NGX_HTTP_AIO_SENDFILE);
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index 0a9b761cd..431b1e52b 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -12,6 +12,8 @@
static ngx_int_t ngx_http_file_cache_read(ngx_http_request_t *r,
ngx_http_cache_t *c);
+static ssize_t ngx_http_file_cache_aio_read(ngx_http_request_t *r,
+ ngx_http_cache_t *c);
#if (NGX_HAVE_FILE_AIO)
static void ngx_http_cache_aio_event_handler(ngx_event_t *ev);
#endif
@@ -330,36 +332,9 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
c = r->cache;
-#if (NGX_HAVE_FILE_AIO)
- {
- ngx_http_core_loc_conf_t *clcf;
-
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
- if (clcf->aio) {
- n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool);
-
- if (n == NGX_AGAIN) {
- c->file.aio->data = r;
- c->file.aio->handler = ngx_http_cache_aio_event_handler;
-
- r->main->blocked++;
- r->aio = 1;
-
- return NGX_AGAIN;
- }
-
- } else {
- n = ngx_read_file(&c->file, c->buf->pos, c->body_start, 0);
- }
- }
-#else
-
- n = ngx_read_file(&c->file, c->buf->pos, c->body_start, 0);
+ n = ngx_http_file_cache_aio_read(r, c);
-#endif
-
- if (n == NGX_ERROR) {
+ if (n < 0) {
return n;
}
@@ -432,8 +407,46 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
}
+static ssize_t
+ngx_http_file_cache_aio_read(ngx_http_request_t *r, ngx_http_cache_t *c)
+{
#if (NGX_HAVE_FILE_AIO)
+ ssize_t n;
+ ngx_http_core_loc_conf_t *clcf;
+ if (!ngx_file_aio) {
+ goto noaio;
+ }
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (!clcf->aio) {
+ goto noaio;
+ }
+
+ n = ngx_file_aio_read(&c->file, c->buf->pos, c->body_start, 0, r->pool);
+
+ if (n != NGX_AGAIN) {
+ return n;
+ }
+
+ c->file.aio->data = r;
+ c->file.aio->handler = ngx_http_cache_aio_event_handler;
+
+ r->main->blocked++;
+ r->aio = 1;
+
+ return NGX_AGAIN;
+
+noaio:
+
+#endif
+
+ return ngx_read_file(&c->file, c->buf->pos, c->body_start, 0);
+}
+
+
+#if (NGX_HAVE_FILE_AIO)
static void
ngx_http_cache_aio_event_handler(ngx_event_t *ev)
diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c
index 5d9be1484..0bc422a01 100644
--- a/src/mail/ngx_mail_smtp_handler.c
+++ b/src/mail/ngx_mail_smtp_handler.c
@@ -191,7 +191,7 @@ ngx_mail_smtp_resolve_name_handler(ngx_resolver_ctx_t *ctx)
if (ctx->state) {
ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "%V could not be resolved (%i: %s)",
+ "\"%V\" could not be resolved (%i: %s)",
&ctx->name, ctx->state,
ngx_resolver_strerror(ctx->state));
diff --git a/src/os/unix/ngx_file_aio_read.c b/src/os/unix/ngx_file_aio_read.c
index 19a75890c..ef7a46107 100644
--- a/src/os/unix/ngx_file_aio_read.c
+++ b/src/os/unix/ngx_file_aio_read.c
@@ -39,12 +39,11 @@ ssize_t
ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
ngx_pool_t *pool)
{
- int n;
- ngx_event_t *ev;
- ngx_event_aio_t *aio;
- static ngx_uint_t enosys = 0;
+ int n;
+ ngx_event_t *ev;
+ ngx_event_aio_t *aio;
- if (enosys) {
+ if (!ngx_file_aio) {
return ngx_read_file(file, buf, size, offset);
}
@@ -116,7 +115,7 @@ ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
"aio_read(\"%V\") failed", &file->name);
if (n == NGX_ENOSYS) {
- enosys = 1;
+ ngx_file_aio = 0;
return ngx_read_file(file, buf, size, offset);
}
diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c
index 618d4e214..2264cc13e 100644
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -8,6 +8,13 @@
#include <ngx_core.h>
+#if (NGX_HAVE_FILE_AIO)
+
+ngx_uint_t ngx_file_aio = 1;
+
+#endif
+
+
ssize_t
ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset)
{
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 966262143..2efd24778 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -313,6 +313,8 @@ size_t ngx_fs_bsize(u_char *name);
ssize_t ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size,
off_t offset, ngx_pool_t *pool);
+extern ngx_uint_t ngx_file_aio;
+
#endif
diff --git a/src/os/unix/ngx_linux_aio_read.c b/src/os/unix/ngx_linux_aio_read.c
index 3b4185c8b..834a11d07 100644
--- a/src/os/unix/ngx_linux_aio_read.c
+++ b/src/os/unix/ngx_linux_aio_read.c
@@ -27,13 +27,12 @@ ssize_t
ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
ngx_pool_t *pool)
{
- long n;
- struct iocb *piocb[1];
- ngx_event_t *ev;
- ngx_event_aio_t *aio;
- static ngx_uint_t enosys = 0;
+ long n;
+ struct iocb *piocb[1];
+ ngx_event_t *ev;
+ ngx_event_aio_t *aio;
- if (enosys) {
+ if (!ngx_file_aio) {
return ngx_read_file(file, buf, size, offset);
}
@@ -109,7 +108,7 @@ ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
"io_submit(\"%V\") failed", &file->name);
if (n == NGX_ENOSYS) {
- enosys = 1;
+ ngx_file_aio = 0;
return ngx_read_file(file, buf, size, offset);
}
diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c
index b38a81009..f21614499 100644
--- a/src/os/unix/ngx_posix_init.c
+++ b/src/os/unix/ngx_posix_init.c
@@ -44,8 +44,6 @@ ngx_os_init(ngx_log_t *log)
ngx_pagesize = getpagesize();
ngx_cacheline_size = NGX_CPU_CACHE_LINE;
- n = ngx_pagesize;
-
for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ }
if (ngx_ncpu == 0) {
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 15a2a8bab..4b7403054 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -86,7 +86,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
u_char *p;
size_t size;
ngx_int_t i;
- ngx_uint_t n;
+ ngx_uint_t n, sigio;
sigset_t set;
struct itimerval itv;
ngx_uint_t live;
@@ -139,11 +139,13 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_new_binary = 0;
delay = 0;
+ sigio = 0;
live = 1;
for ( ;; ) {
if (delay) {
if (ngx_sigalrm) {
+ sigio = 0;
delay *= 2;
ngx_sigalrm = 0;
}
@@ -168,7 +170,8 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_time_update(0, 0);
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "wake up");
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
+ "wake up, sigio %i", sigio);
if (ngx_reap) {
ngx_reap = 0;
@@ -186,6 +189,13 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
delay = 50;
}
+ if (sigio) {
+ sigio--;
+ continue;
+ }
+
+ sigio = ccf->worker_processes + 2 /* cache processes */;
+
if (delay > 1000) {
ngx_signal_worker_processes(cycle, SIGKILL);
} else {