Skip to content

Commit

Permalink
nginx 1.25.4
Browse files Browse the repository at this point in the history
  • Loading branch information
chronolaw committed Apr 19, 2024
2 parents b1861b9 + 7cf9d96 commit b8c2917
Show file tree
Hide file tree
Showing 34 changed files with 572 additions and 197 deletions.
23 changes: 23 additions & 0 deletions nginx/CHANGES
Original file line number Diff line number Diff line change
@@ -1,4 +1,27 @@

Changes with nginx 1.25.4 14 Feb 2024

*) Security: when using HTTP/3 a segmentation fault might occur in a
worker process while processing a specially crafted QUIC session
(CVE-2024-24989, CVE-2024-24990).

*) Bugfix: connections with pending AIO operations might be closed
prematurely during graceful shutdown of old worker processes.

*) Bugfix: socket leak alerts no longer logged when fast shutdown was
requested after graceful shutdown of old worker processes.

*) Bugfix: a socket descriptor error, a socket leak, or a segmentation
fault in a worker process (for SSL proxying) might occur if AIO was
used in a subrequest.

*) Bugfix: a segmentation fault might occur in a worker process if SSL
proxying was used along with the "image_filter" directive and errors
with code 415 were redirected with the "error_page" directive.

*) Bugfixes and improvements in HTTP/3.


Changes with nginx 1.25.3 24 Oct 2023

*) Change: improved detection of misbehaving clients when using HTTP/2.
Expand Down
25 changes: 25 additions & 0 deletions nginx/CHANGES.ru
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@

Изменения в nginx 1.25.4 14.02.2024

*) Безопасность: при использовании HTTP/3 в рабочем процессе мог
произойти segmentation fault во время обработки специально созданной
QUIC-сессии (CVE-2024-24989, CVE-2024-24990).

*) Исправление: соединения с незавершенными AIO-операциями могли
закрываться преждевременно во время плавного завершения старых
рабочих процессов.

*) Исправление: теперь nginx не пишет в лог сообщения об утечке сокетов,
если во время плавного завершения старых рабочих процессов было
запрошено быстрое завершение.

*) Исправление: при использовании AIO в подзапросе могла происходить
ошибка на сокете, утечка сокетов, либо segmentation fault в рабочем
процессе (при SSL-проксировании).

*) Исправление: в рабочем процессе мог произойти segmentation fault,
если использовалось SSL-проксирование и директива image_filter, а
ошибки с кодом 415 перенаправлялись с помощью директивы error_page.

*) Исправления и улучшения в HTTP/3.


Изменения в nginx 1.25.3 24.10.2023

*) Изменение: улучшено детектирование некорректного поведения клиентов
Expand Down
2 changes: 1 addition & 1 deletion nginx/LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2021 Igor Sysoev
* Copyright (C) 2011-2023 Nginx, Inc.
* Copyright (C) 2011-2024 Nginx, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down
4 changes: 2 additions & 2 deletions nginx/src/core/nginx.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
// version number format
// 1'015'005

#define nginx_version 1025003
#define NGINX_VERSION "1.25.3"
#define nginx_version 1025004
#define NGINX_VERSION "1.25.4"
#define NGINX_VER "nginx/" NGINX_VERSION

// nginx 1.7之后添加--build=Name选项
Expand Down
18 changes: 11 additions & 7 deletions nginx/src/event/ngx_event_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,8 @@ ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
BIO *rbio, *wbio;
ngx_connection_t *c;

#ifndef SSL_OP_NO_RENEGOTIATION
#if (!defined SSL_OP_NO_RENEGOTIATION \
&& !defined SSL_OP_NO_CLIENT_RENEGOTIATION)

if ((where & SSL_CB_HANDSHAKE_START)
&& SSL_is_server((ngx_ssl_conn_t *) ssl_conn))
Expand Down Expand Up @@ -1861,18 +1862,17 @@ ngx_ssl_handshake(ngx_connection_t *c)
c->read->ready = 1;
c->write->ready = 1;

#ifndef SSL_OP_NO_RENEGOTIATION
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
#if (!defined SSL_OP_NO_RENEGOTIATION \
&& !defined SSL_OP_NO_CLIENT_RENEGOTIATION \
&& defined SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS \
&& OPENSSL_VERSION_NUMBER < 0x10100000L)

/* initial handshake done, disable renegotiation (CVE-2009-3555) */
if (c->ssl->connection->s3 && SSL_is_server(c->ssl->connection)) {
c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
}

#endif
#endif
#endif

#if (defined BIO_get_ktls_send && !NGX_WIN32)

Expand Down Expand Up @@ -2508,7 +2508,8 @@ ngx_ssl_handle_recv(ngx_connection_t *c, int n)
int sslerr;
ngx_err_t err;

#ifndef SSL_OP_NO_RENEGOTIATION
#if (!defined SSL_OP_NO_RENEGOTIATION \
&& !defined SSL_OP_NO_CLIENT_RENEGOTIATION)

if (c->ssl->renegotiation) {
/*
Expand Down Expand Up @@ -5211,6 +5212,9 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
}

curves = ngx_palloc(pool, n * sizeof(int));
if (curves == NULL) {
return NGX_ERROR;
}

n = SSL_get1_curves(c->ssl->connection, curves);
len = 0;
Expand Down
2 changes: 1 addition & 1 deletion nginx/src/event/ngx_event_openssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
// 转化为OpenSSL
#if (defined LIBRESSL_VERSION_NUMBER && OPENSSL_VERSION_NUMBER == 0x20000000L)
#undef OPENSSL_VERSION_NUMBER
#if (LIBRESSL_VERSION_NUMBER >= 0x2080000fL)
#if (LIBRESSL_VERSION_NUMBER >= 0x3050000fL)
#define OPENSSL_VERSION_NUMBER 0x1010000fL
#else
#define OPENSSL_VERSION_NUMBER 0x1000107fL
Expand Down
2 changes: 1 addition & 1 deletion nginx/src/event/ngx_event_openssl_stapling.c
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
ocsp->cert_status = V_OCSP_CERTSTATUS_GOOD;
ocsp->conf = ocf;

#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined LIBRESSL_VERSION_NUMBER)
#if OPENSSL_VERSION_NUMBER >= 0x10100000L

ocsp->certs = SSL_get0_verified_chain(c->ssl->connection);

Expand Down
8 changes: 6 additions & 2 deletions nginx/src/event/ngx_event_pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
do_write = 1;
}

if (p->upstream->fd != (ngx_socket_t) -1) {
if (p->upstream
&& p->upstream->fd != (ngx_socket_t) -1)
{
rev = p->upstream->read;

flags = (rev->eof || rev->error) ? NGX_CLOSE_EVENT : 0;
Expand Down Expand Up @@ -108,7 +110,9 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
ngx_msec_t delay;
ngx_chain_t *chain, *cl, *ln;

if (p->upstream_eof || p->upstream_error || p->upstream_done) {
if (p->upstream_eof || p->upstream_error || p->upstream_done
|| p->upstream == NULL)
{
return NGX_OK;
}

Expand Down
9 changes: 1 addition & 8 deletions nginx/src/event/quic/ngx_event_quic.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,14 +260,7 @@ ngx_quic_new_connection(ngx_connection_t *c, ngx_quic_conf_t *conf,

ngx_queue_init(&qc->free_frames);

qc->avg_rtt = NGX_QUIC_INITIAL_RTT;
qc->rttvar = NGX_QUIC_INITIAL_RTT / 2;
qc->min_rtt = NGX_TIMER_INFINITE;
qc->first_rtt = NGX_TIMER_INFINITE;

/*
* qc->latest_rtt = 0
*/
ngx_quic_init_rtt(qc);

qc->pto.log = c->log;
qc->pto.data = c;
Expand Down
80 changes: 51 additions & 29 deletions nginx/src/event/quic/ngx_event_quic_ack.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,16 +265,16 @@ ngx_quic_handle_ack_frame_range(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx,
}

if (f->pnum == max) {
st->max_pn = f->last;
st->max_pn = f->send_time;
}

/* save earliest and latest send times of frames ack'ed */
if (st->oldest == NGX_TIMER_INFINITE || f->last < st->oldest) {
st->oldest = f->last;
if (st->oldest == NGX_TIMER_INFINITE || f->send_time < st->oldest) {
st->oldest = f->send_time;
}

if (st->newest == NGX_TIMER_INFINITE || f->last > st->newest) {
st->newest = f->last;
if (st->newest == NGX_TIMER_INFINITE || f->send_time > st->newest) {
st->newest = f->send_time;
}

ngx_queue_remove(&f->queue);
Expand Down Expand Up @@ -325,11 +325,15 @@ ngx_quic_congestion_ack(ngx_connection_t *c, ngx_quic_frame_t *f)
qc = ngx_quic_get_connection(c);
cg = &qc->congestion;

if (f->pnum < qc->rst_pnum) {
return;
}

blocked = (cg->in_flight >= cg->window) ? 1 : 0;

cg->in_flight -= f->plen;

timer = f->last - cg->recovery_start;
timer = f->send_time - cg->recovery_start;

if ((ngx_msec_int_t) timer <= 0) {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
Expand Down Expand Up @@ -465,7 +469,7 @@ ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st)
break;
}

wait = start->last + thr - now;
wait = start->send_time + thr - now;

ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic detect_lost pnum:%uL thr:%M wait:%i level:%d",
Expand All @@ -477,14 +481,14 @@ ngx_quic_detect_lost(ngx_connection_t *c, ngx_quic_ack_stat_t *st)
break;
}

if (start->last > qc->first_rtt) {
if (start->send_time > qc->first_rtt) {

if (oldest == NGX_TIMER_INFINITE || start->last < oldest) {
oldest = start->last;
if (oldest == NGX_TIMER_INFINITE || start->send_time < oldest) {
oldest = start->send_time;
}

if (newest == NGX_TIMER_INFINITE || start->last > newest) {
newest = start->last;
if (newest == NGX_TIMER_INFINITE || start->send_time > newest) {
newest = start->send_time;
}

nlost++;
Expand Down Expand Up @@ -593,6 +597,7 @@ ngx_quic_resend_frames(ngx_connection_t *c, ngx_quic_send_ctx_t *ctx)
break;

case NGX_QUIC_FT_PING:
case NGX_QUIC_FT_PATH_CHALLENGE:
case NGX_QUIC_FT_PATH_RESPONSE:
case NGX_QUIC_FT_CONNECTION_CLOSE:
ngx_quic_free_frame(c, f);
Expand Down Expand Up @@ -666,12 +671,16 @@ ngx_quic_congestion_lost(ngx_connection_t *c, ngx_quic_frame_t *f)
qc = ngx_quic_get_connection(c);
cg = &qc->congestion;

if (f->pnum < qc->rst_pnum) {
return;
}

blocked = (cg->in_flight >= cg->window) ? 1 : 0;

cg->in_flight -= f->plen;
f->plen = 0;

timer = f->last - cg->recovery_start;
timer = f->send_time - cg->recovery_start;

if ((ngx_msec_int_t) timer <= 0) {
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
Expand Down Expand Up @@ -729,7 +738,8 @@ ngx_quic_set_lost_timer(ngx_connection_t *c)
if (ctx->largest_ack != NGX_QUIC_UNSET_PN) {
q = ngx_queue_head(&ctx->sent);
f = ngx_queue_data(q, ngx_quic_frame_t, queue);
w = (ngx_msec_int_t) (f->last + ngx_quic_lost_threshold(qc) - now);
w = (ngx_msec_int_t)
(f->send_time + ngx_quic_lost_threshold(qc) - now);

if (f->pnum <= ctx->largest_ack) {
if (w < 0 || ctx->largest_ack - f->pnum >= NGX_QUIC_PKT_THR) {
Expand All @@ -744,8 +754,8 @@ ngx_quic_set_lost_timer(ngx_connection_t *c)

q = ngx_queue_last(&ctx->sent);
f = ngx_queue_data(q, ngx_quic_frame_t, queue);
w = (ngx_msec_int_t) (f->last + (ngx_quic_pto(c, ctx) << qc->pto_count)
- now);
w = (ngx_msec_int_t)
(f->send_time + (ngx_quic_pto(c, ctx) << qc->pto_count) - now);

if (w < 0) {
w = 0;
Expand Down Expand Up @@ -824,11 +834,12 @@ void ngx_quic_lost_handler(ngx_event_t *ev)
void
ngx_quic_pto_handler(ngx_event_t *ev)
{
ngx_uint_t i;
ngx_uint_t i, n;
ngx_msec_t now;
ngx_queue_t *q;
ngx_msec_int_t w;
ngx_connection_t *c;
ngx_quic_frame_t *f, frame;
ngx_quic_frame_t *f;
ngx_quic_send_ctx_t *ctx;
ngx_quic_connection_t *qc;

Expand All @@ -848,33 +859,37 @@ ngx_quic_pto_handler(ngx_event_t *ev)

q = ngx_queue_last(&ctx->sent);
f = ngx_queue_data(q, ngx_quic_frame_t, queue);
w = (ngx_msec_int_t)
(f->send_time + (ngx_quic_pto(c, ctx) << qc->pto_count) - now);

if (f->pnum <= ctx->largest_ack
&& ctx->largest_ack != NGX_QUIC_UNSET_PN)
{
continue;
}

if ((ngx_msec_int_t) (f->last + (ngx_quic_pto(c, ctx) << qc->pto_count)
- now) > 0)
{
if (w > 0) {
continue;
}

ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
"quic pto %s pto_count:%ui",
ngx_quic_level_name(ctx->level), qc->pto_count);

ngx_memzero(&frame, sizeof(ngx_quic_frame_t));
for (n = 0; n < 2; n++) {

frame.level = ctx->level;
frame.type = NGX_QUIC_FT_PING;
f = ngx_quic_alloc_frame(c);
if (f == NULL) {
goto failed;
}

if (ngx_quic_frame_sendto(c, &frame, 0, qc->path) != NGX_OK
|| ngx_quic_frame_sendto(c, &frame, 0, qc->path) != NGX_OK)
{
ngx_quic_close_connection(c, NGX_ERROR);
return;
f->level = ctx->level;
f->type = NGX_QUIC_FT_PING;
f->ignore_congestion = 1;

if (ngx_quic_frame_sendto(c, f, 0, qc->path) == NGX_ERROR) {
goto failed;
}
}
}

Expand All @@ -883,6 +898,13 @@ ngx_quic_pto_handler(ngx_event_t *ev)
ngx_quic_set_lost_timer(c);

ngx_quic_connstate_dbg(c);

return;

failed:

ngx_quic_close_connection(c, NGX_ERROR);
return;
}


Expand Down
Loading

0 comments on commit b8c2917

Please sign in to comment.