diff options
Diffstat (limited to 'meta-webserver/recipes-httpd/nginx')
5 files changed, 457 insertions, 0 deletions
diff --git a/meta-webserver/recipes-httpd/nginx/files/0001-HTTP-2-per-iteration-stream-handling-limit.patch b/meta-webserver/recipes-httpd/nginx/files/0001-HTTP-2-per-iteration-stream-handling-limit.patch new file mode 100644 index 0000000000..7dd1e721c0 --- /dev/null +++ b/meta-webserver/recipes-httpd/nginx/files/0001-HTTP-2-per-iteration-stream-handling-limit.patch @@ -0,0 +1,92 @@ +From 2b9667f36551406169e3e2a6a774466ac70a83c0 Mon Sep 17 00:00:00 2001 +From: Maxim Dounin <mdounin@mdounin.ru> +Date: Tue, 10 Oct 2023 15:13:39 +0300 +Subject: [PATCH] HTTP/2: per-iteration stream handling limit. + +To ensure that attempts to flood servers with many streams are detected +early, a limit of no more than 2 * max_concurrent_streams new streams per one +event loop iteration was introduced. This limit is applied even if +max_concurrent_streams is not yet reached - for example, if corresponding +streams are handled synchronously or reset. + +Further, refused streams are now limited to maximum of max_concurrent_streams +and 100, similarly to priority_limit initial value, providing some tolerance +to clients trying to open several streams at the connection start, yet +low tolerance to flooding attempts. + +Upstream-Status: Backport +[https://github.com/nginx/nginx/commit/6ceef192e7af1c507826ac38a2d43f08bf265fb9] + +Reduces the impact of HTTP/2 Stream Reset flooding in the nginx product +(CVE-2023-44487). + +See: https://www.nginx.com/blog/http-2-rapid-reset-attack-impacting-f5-nginx-products/ + +This patch only reduces the impact and does not completely mitigate the CVE +in question, the latter being due to a design flaw in the HTTP/2 protocol +itself. For transparancy reasons I therefore opted to not mark the +CVE as resolved, so that integrators can decide for themselves, wheither to +enable HTTP/2 support or allow HTTP/1.1 connections only. + +Signed-off-by: Jasper Orschulko <jasper@fancydomain.eu> +--- + src/http/v2/ngx_http_v2.c | 15 +++++++++++++++ + src/http/v2/ngx_http_v2.h | 2 ++ + 2 files changed, 17 insertions(+) + +diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c +index 3611a2e50..291677aca 100644 +--- a/src/http/v2/ngx_http_v2.c ++++ b/src/http/v2/ngx_http_v2.c +@@ -361,6 +361,7 @@ ngx_http_v2_read_handler(ngx_event_t *rev) + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http2 read handler"); + + h2c->blocked = 1; ++ h2c->new_streams = 0; + + if (c->close) { + c->close = 0; +@@ -1320,6 +1321,14 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos, + goto rst_stream; + } + ++ if (h2c->new_streams++ >= 2 * h2scf->concurrent_streams) { ++ ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, ++ "client sent too many streams at once"); ++ ++ status = NGX_HTTP_V2_REFUSED_STREAM; ++ goto rst_stream; ++ } ++ + if (!h2c->settings_ack + && !(h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG) + && h2scf->preread_size < NGX_HTTP_V2_DEFAULT_WINDOW) +@@ -1385,6 +1394,12 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos, + + rst_stream: + ++ if (h2c->refused_streams++ > ngx_max(h2scf->concurrent_streams, 100)) { ++ ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, ++ "client sent too many refused streams"); ++ return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_NO_ERROR); ++ } ++ + if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid, status) != NGX_OK) { + return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); + } +diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h +index 349229711..6a7aaa62c 100644 +--- a/src/http/v2/ngx_http_v2.h ++++ b/src/http/v2/ngx_http_v2.h +@@ -125,6 +125,8 @@ struct ngx_http_v2_connection_s { + ngx_uint_t processing; + ngx_uint_t frames; + ngx_uint_t idle; ++ ngx_uint_t new_streams; ++ ngx_uint_t refused_streams; + ngx_uint_t priority_limit; + + ngx_uint_t pushing; +-- +2.42.1 + diff --git a/meta-webserver/recipes-httpd/nginx/files/CVE-2019-20372.patch b/meta-webserver/recipes-httpd/nginx/files/CVE-2019-20372.patch new file mode 100644 index 0000000000..45653e422e --- /dev/null +++ b/meta-webserver/recipes-httpd/nginx/files/CVE-2019-20372.patch @@ -0,0 +1,39 @@ +From 6511195c023bf03e0fb19a36f41f42f4edde6e88 Mon Sep 17 00:00:00 2001 +From: Ruslan Ermilov <ru@nginx.com> +Date: Mon, 23 Dec 2019 15:45:46 +0300 +Subject: [PATCH] Discard request body when redirecting to a URL via + error_page. + +Reported by Bert JW Regeer and Francisco Oca Gonzalez. + +Upstream-Status: Backport +CVE: CVE-2019-20372 + +Reference to upstream patch: +https://github.com/nginx/nginx/commit/c1be55f97211d38b69ac0c2027e6812ab8b1b94e + +Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org> +--- + src/http/ngx_http_special_response.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c +index 4ffb2cc8..76e67058 100644 +--- a/src/http/ngx_http_special_response.c ++++ b/src/http/ngx_http_special_response.c +@@ -623,6 +623,12 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page) + return ngx_http_named_location(r, &uri); + } + ++ r->expect_tested = 1; ++ ++ if (ngx_http_discard_request_body(r) != NGX_OK) { ++ r->keepalive = 0; ++ } ++ + location = ngx_list_push(&r->headers_out.headers); + + if (location == NULL) { +-- +2.17.1 + diff --git a/meta-webserver/recipes-httpd/nginx/files/CVE-2022-41741-CVE-2022-41742.patch b/meta-webserver/recipes-httpd/nginx/files/CVE-2022-41741-CVE-2022-41742.patch new file mode 100644 index 0000000000..8a8a35b2dd --- /dev/null +++ b/meta-webserver/recipes-httpd/nginx/files/CVE-2022-41741-CVE-2022-41742.patch @@ -0,0 +1,319 @@ +From 9563a2a08c007d78a6796b0232201bf7dc4a8103 Mon Sep 17 00:00:00 2001 +From: Hitendra Prajapati <hprajapati@mvista.com> +Date: Wed, 16 Nov 2022 10:28:24 +0530 +Subject: [PATCH] CVE-2022-41741, CVE-2022-41742 + +Upstream-Status: Backport [https://github.com/nginx/nginx/commit/6b022a5556af22b6e18532e547a6ae46b0d8c6ea] +CVE: CVE-2022-41741, CVE-2022-41742 +Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> + +Mp4: disabled duplicate atoms. + +Most atoms should not appear more than once in a container. Previously, +this was not enforced by the module, which could result in worker process +crash, memory corruption and disclosure. +--- + src/http/modules/ngx_http_mp4_module.c | 147 +++++++++++++++++++++++++ + 1 file changed, 147 insertions(+) + +diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c +index 618bf78..7b7184d 100644 +--- a/src/http/modules/ngx_http_mp4_module.c ++++ b/src/http/modules/ngx_http_mp4_module.c +@@ -1076,6 +1076,12 @@ ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + return NGX_ERROR; + } + ++ if (mp4->ftyp_atom.buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 ftyp atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; + + ftyp_atom = ngx_palloc(mp4->request->pool, atom_size); +@@ -1134,6 +1140,12 @@ ngx_http_mp4_read_moov_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + return NGX_DECLINED; + } + ++ if (mp4->moov_atom.buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 moov atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + conf = ngx_http_get_module_loc_conf(mp4->request, ngx_http_mp4_module); + + if (atom_data_size > mp4->buffer_size) { +@@ -1201,6 +1213,12 @@ ngx_http_mp4_read_mdat_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mdat atom"); + ++ if (mp4->mdat_atom.buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 mdat atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + data = &mp4->mdat_data_buf; + data->file = &mp4->file; + data->in_file = 1; +@@ -1327,6 +1345,12 @@ ngx_http_mp4_read_mvhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 mvhd atom"); + ++ if (mp4->mvhd_atom.buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 mvhd atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + atom_header = ngx_mp4_atom_header(mp4); + mvhd_atom = (ngx_mp4_mvhd_atom_t *) atom_header; + mvhd64_atom = (ngx_mp4_mvhd64_atom_t *) atom_header; +@@ -1592,6 +1616,13 @@ ngx_http_mp4_read_tkhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; + + trak = ngx_mp4_last_trak(mp4); ++ ++ if (trak->out[NGX_HTTP_MP4_TKHD_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 tkhd atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + trak->tkhd_size = atom_size; + + ngx_mp4_set_32value(tkhd_atom->size, atom_size); +@@ -1630,6 +1661,12 @@ ngx_http_mp4_read_mdia_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + + trak = ngx_mp4_last_trak(mp4); + ++ if (trak->out[NGX_HTTP_MP4_MDIA_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 mdia atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + atom = &trak->mdia_atom_buf; + atom->temporary = 1; + atom->pos = atom_header; +@@ -1753,6 +1790,13 @@ ngx_http_mp4_read_mdhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + atom_size = sizeof(ngx_mp4_atom_header_t) + (size_t) atom_data_size; + + trak = ngx_mp4_last_trak(mp4); ++ ++ if (trak->out[NGX_HTTP_MP4_MDHD_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 mdhd atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + trak->mdhd_size = atom_size; + trak->timescale = timescale; + +@@ -1795,6 +1839,12 @@ ngx_http_mp4_read_hdlr_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + + trak = ngx_mp4_last_trak(mp4); + ++ if (trak->out[NGX_HTTP_MP4_HDLR_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 hdlr atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + atom = &trak->hdlr_atom_buf; + atom->temporary = 1; + atom->pos = atom_header; +@@ -1823,6 +1873,12 @@ ngx_http_mp4_read_minf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + + trak = ngx_mp4_last_trak(mp4); + ++ if (trak->out[NGX_HTTP_MP4_MINF_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 minf atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + atom = &trak->minf_atom_buf; + atom->temporary = 1; + atom->pos = atom_header; +@@ -1866,6 +1922,15 @@ ngx_http_mp4_read_vmhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + + trak = ngx_mp4_last_trak(mp4); + ++ if (trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf ++ || trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf) ++ { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 vmhd/smhd atom in \"%s\"", ++ mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + atom = &trak->vmhd_atom_buf; + atom->temporary = 1; + atom->pos = atom_header; +@@ -1897,6 +1962,15 @@ ngx_http_mp4_read_smhd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + + trak = ngx_mp4_last_trak(mp4); + ++ if (trak->out[NGX_HTTP_MP4_VMHD_ATOM].buf ++ || trak->out[NGX_HTTP_MP4_SMHD_ATOM].buf) ++ { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 vmhd/smhd atom in \"%s\"", ++ mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + atom = &trak->smhd_atom_buf; + atom->temporary = 1; + atom->pos = atom_header; +@@ -1928,6 +2002,12 @@ ngx_http_mp4_read_dinf_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + + trak = ngx_mp4_last_trak(mp4); + ++ if (trak->out[NGX_HTTP_MP4_DINF_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 dinf atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + atom = &trak->dinf_atom_buf; + atom->temporary = 1; + atom->pos = atom_header; +@@ -1956,6 +2036,12 @@ ngx_http_mp4_read_stbl_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + + trak = ngx_mp4_last_trak(mp4); + ++ if (trak->out[NGX_HTTP_MP4_STBL_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 stbl atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + atom = &trak->stbl_atom_buf; + atom->temporary = 1; + atom->pos = atom_header; +@@ -2024,6 +2110,12 @@ ngx_http_mp4_read_stsd_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + + trak = ngx_mp4_last_trak(mp4); + ++ if (trak->out[NGX_HTTP_MP4_STSD_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 stsd atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + atom = &trak->stsd_atom_buf; + atom->temporary = 1; + atom->pos = atom_header; +@@ -2092,6 +2184,13 @@ ngx_http_mp4_read_stts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + atom_end = atom_table + entries * sizeof(ngx_mp4_stts_entry_t); + + trak = ngx_mp4_last_trak(mp4); ++ ++ if (trak->out[NGX_HTTP_MP4_STTS_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 stts atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + trak->time_to_sample_entries = entries; + + atom = &trak->stts_atom_buf; +@@ -2297,6 +2396,13 @@ ngx_http_mp4_read_stss_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + "sync sample entries:%uD", entries); + + trak = ngx_mp4_last_trak(mp4); ++ ++ if (trak->out[NGX_HTTP_MP4_STSS_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 stss atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + trak->sync_samples_entries = entries; + + atom_table = atom_header + sizeof(ngx_http_mp4_stss_atom_t); +@@ -2495,6 +2601,13 @@ ngx_http_mp4_read_ctts_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + "composition offset entries:%uD", entries); + + trak = ngx_mp4_last_trak(mp4); ++ ++ if (trak->out[NGX_HTTP_MP4_CTTS_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 ctts atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + trak->composition_offset_entries = entries; + + atom_table = atom_header + sizeof(ngx_mp4_ctts_atom_t); +@@ -2698,6 +2811,13 @@ ngx_http_mp4_read_stsc_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + atom_end = atom_table + entries * sizeof(ngx_mp4_stsc_entry_t); + + trak = ngx_mp4_last_trak(mp4); ++ ++ if (trak->out[NGX_HTTP_MP4_STSC_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 stsc atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + trak->sample_to_chunk_entries = entries; + + atom = &trak->stsc_atom_buf; +@@ -3030,6 +3150,13 @@ ngx_http_mp4_read_stsz_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + "sample uniform size:%uD, entries:%uD", size, entries); + + trak = ngx_mp4_last_trak(mp4); ++ ++ if (trak->out[NGX_HTTP_MP4_STSZ_ATOM].buf) { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 stsz atom in \"%s\"", mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + trak->sample_sizes_entries = entries; + + atom_table = atom_header + sizeof(ngx_mp4_stsz_atom_t); +@@ -3199,6 +3326,16 @@ ngx_http_mp4_read_stco_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + atom_end = atom_table + entries * sizeof(uint32_t); + + trak = ngx_mp4_last_trak(mp4); ++ ++ if (trak->out[NGX_HTTP_MP4_STCO_ATOM].buf ++ || trak->out[NGX_HTTP_MP4_CO64_ATOM].buf) ++ { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 stco/co64 atom in \"%s\"", ++ mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + trak->chunks = entries; + + atom = &trak->stco_atom_buf; +@@ -3383,6 +3520,16 @@ ngx_http_mp4_read_co64_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size) + atom_end = atom_table + entries * sizeof(uint64_t); + + trak = ngx_mp4_last_trak(mp4); ++ ++ if (trak->out[NGX_HTTP_MP4_STCO_ATOM].buf ++ || trak->out[NGX_HTTP_MP4_CO64_ATOM].buf) ++ { ++ ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0, ++ "duplicate mp4 stco/co64 atom in \"%s\"", ++ mp4->file.name.data); ++ return NGX_ERROR; ++ } ++ + trak->chunks = entries; + + atom = &trak->co64_atom_buf; +-- +2.25.1 + diff --git a/meta-webserver/recipes-httpd/nginx/nginx_1.16.1.bb b/meta-webserver/recipes-httpd/nginx/nginx_1.16.1.bb index 207642575b..39cfd3a67b 100644 --- a/meta-webserver/recipes-httpd/nginx/nginx_1.16.1.bb +++ b/meta-webserver/recipes-httpd/nginx/nginx_1.16.1.bb @@ -4,3 +4,8 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=52e384aaac868b755b93ad5535e2d075" SRC_URI[md5sum] = "45a80f75336c980d240987badc3dcf60" SRC_URI[sha256sum] = "f11c2a6dd1d3515736f0324857957db2de98be862461b5a542a3ac6188dbe32b" + +SRC_URI += "file://CVE-2019-20372.patch \ + file://CVE-2022-41741-CVE-2022-41742.patch \ + file://0001-HTTP-2-per-iteration-stream-handling-limit.patch \ + " diff --git a/meta-webserver/recipes-httpd/nginx/nginx_1.17.8.bb b/meta-webserver/recipes-httpd/nginx/nginx_1.17.8.bb index 3d2a5edd26..9fd6d73428 100644 --- a/meta-webserver/recipes-httpd/nginx/nginx_1.17.8.bb +++ b/meta-webserver/recipes-httpd/nginx/nginx_1.17.8.bb @@ -8,3 +8,5 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=52e384aaac868b755b93ad5535e2d075" SRC_URI[md5sum] = "29cd861a13aae69a058cbabaae86177b" SRC_URI[sha256sum] = "97d23ecf6d5150b30e284b40e8a6f7e3bb5be6b601e373a4d013768d5a25965b" + +SRC_URI += "file://0001-HTTP-2-per-iteration-stream-handling-limit.patch" |