Version in base suite: 1.52.0-1+deb12u2 Base version: nghttp2_1.52.0-1+deb12u2 Target version: nghttp2_1.52.0-1+deb12u3 Base file: /srv/ftp-master.debian.org/ftp/pool/main/n/nghttp2/nghttp2_1.52.0-1+deb12u2.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/n/nghttp2/nghttp2_1.52.0-1+deb12u3.dsc changelog | 9 patches/CVE-2026-27135-test.patch | 465 ++++++++++++++++++++++++++++++++++++++ patches/CVE-2026-27135.patch | 114 +++++++++ patches/series | 2 4 files changed, 590 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmppe4k53at/nghttp2_1.52.0-1+deb12u2.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmppe4k53at/nghttp2_1.52.0-1+deb12u3.dsc: no acceptable signature found diff -Nru nghttp2-1.52.0/debian/changelog nghttp2-1.52.0/debian/changelog --- nghttp2-1.52.0/debian/changelog 2024-09-27 13:25:38.000000000 +0000 +++ nghttp2-1.52.0/debian/changelog 2026-04-15 14:23:22.000000000 +0000 @@ -1,3 +1,12 @@ +nghttp2 (1.52.0-1+deb12u3) bookworm-security; urgency=high + + * Non-maintainer upload by the Security Team. + * CVE-2026-27135 (Closes: #1131369) + Fix missing iframe->state validations to avoid assertion failure. + * Add test for CVE-2026-27135 (cherry-picked from upstream c619c7b) + + -- Lukas Märdian Wed, 15 Apr 2026 16:23:22 +0200 + nghttp2 (1.52.0-1+deb12u2) bookworm; urgency=medium * Non-maintainer upload. diff -Nru nghttp2-1.52.0/debian/patches/CVE-2026-27135-test.patch nghttp2-1.52.0/debian/patches/CVE-2026-27135-test.patch --- nghttp2-1.52.0/debian/patches/CVE-2026-27135-test.patch 1970-01-01 00:00:00.000000000 +0000 +++ nghttp2-1.52.0/debian/patches/CVE-2026-27135-test.patch 2026-04-15 14:23:22.000000000 +0000 @@ -0,0 +1,465 @@ +From: Tatsuhiro Tsujikawa +Date: Wed, 18 Feb 2026 20:47:36 +0900 +Subject: Add tests for iframe->state validation + +Backport: Adapted from upstream commit c619c7b +Converted from munit to CUnit test framework. Changed +nghttp2_session_mem_recv2/nghttp2_ssize to nghttp2_session_mem_recv/ssize_t. +Added session->pending_no_rfc7540_priorities = 1 for PRIORITY_UPDATE +sub-tests because upstream removed the session_no_rfc7540_pri_no_fallback check. + +Origin: backport, https://github.com/nghttp2/nghttp2/commit/c619c7be0737ac78051b1cacf4b1ce5467eb838d +Refresh: context updated for tests/main.c and tests/nghttp2_session_test.h +to account for the test_nghttp2_session_stream_reset_ratelim entry added +by the local CVE-2023-44487.patch in this bookworm source tree. +--- +--- a/tests/main.c ++++ b/tests/main.c +@@ -344,6 +344,8 @@ int main(void) { + test_nghttp2_session_no_rfc7540_priorities) || + !CU_add_test(pSuite, "session_server_fallback_rfc7540_priorities", + test_nghttp2_session_server_fallback_rfc7540_priorities) || ++ !CU_add_test(pSuite, "session_verify_iframe_state", ++ test_nghttp2_session_verify_iframe_state) || + !CU_add_test(pSuite, "session_stream_reset_ratelim", + test_nghttp2_session_stream_reset_ratelim) || + !CU_add_test(pSuite, "http_mandatory_headers", +--- a/tests/nghttp2_session_test.c ++++ b/tests/nghttp2_session_test.c +@@ -12048,6 +12048,426 @@ void test_nghttp2_session_stream_reset_r + nghttp2_option_del(option); + } + ++static int term_session_on_invalid_frame_recv_callback( ++ nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, ++ void *user_data) { ++ int rv; ++ (void)frame; ++ (void)lib_error_code; ++ (void)user_data; ++ ++ rv = nghttp2_session_terminate_session(session, NGHTTP2_NO_ERROR); ++ ++ CU_ASSERT(0 == rv); ++ ++ return 0; ++} ++ ++static int term_session_on_begin_frame_callback(nghttp2_session *session, ++ const nghttp2_frame_hd *hd, ++ void *user_data) { ++ int rv; ++ (void)hd; ++ (void)user_data; ++ ++ rv = nghttp2_session_terminate_session(session, NGHTTP2_NO_ERROR); ++ ++ CU_ASSERT(0 == rv); ++ ++ return 0; ++} ++ ++static int term_session_on_frame_recv_callback(nghttp2_session *session, ++ const nghttp2_frame *frame, ++ void *user_data) { ++ int rv; ++ (void)frame; ++ (void)user_data; ++ ++ rv = nghttp2_session_terminate_session(session, NGHTTP2_NO_ERROR); ++ ++ CU_ASSERT(0 == rv); ++ ++ return 0; ++} ++ ++static int term_session_on_data_chunk_recv_callback( ++ nghttp2_session *session, uint8_t flags, int32_t stream_id, ++ const uint8_t *data, size_t len, void *user_data) { ++ int rv; ++ (void)flags; ++ (void)stream_id; ++ (void)data; ++ (void)len; ++ (void)user_data; ++ ++ rv = nghttp2_session_terminate_session(session, NGHTTP2_NO_ERROR); ++ ++ CU_ASSERT(0 == rv); ++ ++ return 0; ++} ++ ++static int term_session_unpack_extension_callback(nghttp2_session *session, ++ void **payload, ++ const nghttp2_frame_hd *hd, ++ void *user_data) { ++ int rv; ++ (void)payload; ++ (void)hd; ++ (void)user_data; ++ ++ rv = nghttp2_session_terminate_session(session, NGHTTP2_NO_ERROR); ++ ++ CU_ASSERT(0 == rv); ++ ++ return 0; ++} ++ ++static int term_session_on_extension_chunk_recv_callback( ++ nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data, ++ size_t len, void *user_data) { ++ int rv; ++ (void)hd; ++ (void)data; ++ (void)len; ++ (void)user_data; ++ ++ rv = nghttp2_session_terminate_session(session, NGHTTP2_NO_ERROR); ++ ++ CU_ASSERT(0 == rv); ++ ++ return NGHTTP2_ERR_CANCEL; ++} ++ ++void test_nghttp2_session_verify_iframe_state(void) { ++ nghttp2_session *session; ++ nghttp2_session_callbacks callbacks; ++ nghttp2_bufs bufs; ++ nghttp2_buf *buf; ++ nghttp2_frame frame; ++ nghttp2_extension extfr; ++ nghttp2_ext_priority_update priority_update; ++ nghttp2_ext_altsvc altsvc; ++ nghttp2_frame_hd hd; ++ uint8_t size_err_hd[NGHTTP2_FRAME_HDLEN]; ++ ssize_t rv; ++ const char field_value[] = "i"; ++ nghttp2_option *option; ++ nghttp2_hd_deflater deflater; ++ size_t nvlen; ++ nghttp2_nv *nva; ++ nghttp2_mem *mem = nghttp2_mem_default(); ++ my_user_data ud; ++ nghttp2_buf udbuf; ++ const char uddata[] = "hello world"; ++ ++ nghttp2_frame_hd_init(&hd, 0, NGHTTP2_RST_STREAM, NGHTTP2_FLAG_NONE, 1); ++ nghttp2_frame_pack_frame_hd(size_err_hd, &hd); ++ ++ nghttp2_buf_init2(&ud.scratchbuf, 4096, mem); ++ nghttp2_buf_init2(&udbuf, 4096, mem); ++ ++ nghttp2_frame_hd_init(&hd, sizeof(uddata) - 1, 111, 0xab, 1000000007); ++ nghttp2_frame_pack_frame_hd(udbuf.last, &hd); ++ udbuf.last += NGHTTP2_FRAME_HDLEN; ++ udbuf.last = nghttp2_cpymem(udbuf.last, uddata, sizeof(uddata) - 1); ++ ++ nghttp2_option_new(&option); ++ nghttp2_option_set_builtin_recv_extension_type(option, ++ NGHTTP2_PRIORITY_UPDATE); ++ nghttp2_option_set_builtin_recv_extension_type(option, NGHTTP2_ALTSVC); ++ nghttp2_option_set_user_recv_extension_type(option, 111); ++ ++ frame_pack_bufs_init(&bufs); ++ ++ /* ALTSVC + on_invalid_frame_recv_callback + FRAME_SIZE_ERROR */ ++ memset(&callbacks, 0, sizeof(callbacks)); ++ callbacks.on_invalid_frame_recv_callback = ++ term_session_on_invalid_frame_recv_callback; ++ ++ nghttp2_session_client_new2(&session, &callbacks, NULL, option); ++ ++ extfr.payload = &altsvc; ++ nghttp2_frame_altsvc_init(&extfr, 0, NULL, 0, NULL, 0); ++ nghttp2_bufs_reset(&bufs); ++ nghttp2_frame_pack_altsvc(&bufs, &extfr); ++ ++ buf = &bufs.head->buf; ++ ++ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_bufs_len(&bufs)); ++ ++ CU_ASSERT((ssize_t)nghttp2_bufs_len(&bufs) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ rv = nghttp2_session_mem_recv(session, size_err_hd, sizeof(size_err_hd)); ++ ++ CU_ASSERT((ssize_t)sizeof(size_err_hd) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ nghttp2_session_del(session); ++ ++ /* HEADERS + on_begin_frame_callback + FRAME_SIZE_ERROR */ ++ memset(&callbacks, 0, sizeof(callbacks)); ++ callbacks.on_begin_frame_callback = term_session_on_begin_frame_callback; ++ ++ nghttp2_session_server_new(&session, &callbacks, NULL); ++ ++ nvlen = ARRLEN(reqnv); ++ nghttp2_nv_array_copy(&nva, reqnv, nvlen, mem); ++ nghttp2_frame_headers_init(&frame.headers, NGHTTP2_FLAG_END_HEADERS, 1, ++ NGHTTP2_HCAT_HEADERS, NULL, nva, nvlen); ++ nghttp2_hd_deflate_init(&deflater, mem); ++ nghttp2_bufs_reset(&bufs); ++ rv = nghttp2_frame_pack_headers(&bufs, &frame.headers, &deflater); ++ ++ CU_ASSERT(0 == rv); ++ ++ nghttp2_frame_headers_free(&frame.headers, mem); ++ ++ buf = &bufs.head->buf; ++ ++ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_bufs_len(&bufs)); ++ ++ CU_ASSERT((ssize_t)nghttp2_bufs_len(&bufs) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ rv = nghttp2_session_mem_recv(session, size_err_hd, sizeof(size_err_hd)); ++ ++ CU_ASSERT((ssize_t)sizeof(size_err_hd) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ nghttp2_hd_deflate_free(&deflater); ++ nghttp2_session_del(session); ++ ++ /* Any frame (other than HEADERS) + on_begin_frame_callback + ++ FRAME_SIZE_ERROR */ ++ memset(&callbacks, 0, sizeof(callbacks)); ++ callbacks.on_begin_frame_callback = term_session_on_begin_frame_callback; ++ ++ nghttp2_session_server_new(&session, &callbacks, NULL); ++ ++ nghttp2_frame_rst_stream_init(&frame.rst_stream, 1, NGHTTP2_NO_ERROR); ++ nghttp2_bufs_reset(&bufs); ++ nghttp2_frame_pack_rst_stream(&bufs, &frame.rst_stream); ++ ++ buf = &bufs.head->buf; ++ ++ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_bufs_len(&bufs)); ++ ++ CU_ASSERT((ssize_t)nghttp2_bufs_len(&bufs) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ rv = nghttp2_session_mem_recv(session, size_err_hd, sizeof(size_err_hd)); ++ ++ CU_ASSERT((ssize_t)sizeof(size_err_hd) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ nghttp2_session_del(session); ++ ++ /* PRIORITY_UPDATE + on_frame_recv_callback + FRAME_SIZE_ERROR */ ++ memset(&callbacks, 0, sizeof(callbacks)); ++ callbacks.on_frame_recv_callback = term_session_on_frame_recv_callback; ++ ++ nghttp2_session_server_new2(&session, &callbacks, NULL, option); ++ ++ session->pending_no_rfc7540_priorities = 1; ++ ++ extfr.payload = &priority_update; ++ nghttp2_frame_priority_update_init(&extfr, 1, (uint8_t *)field_value, ++ sizeof(field_value) - 1); ++ nghttp2_bufs_reset(&bufs); ++ nghttp2_frame_pack_priority_update(&bufs, &extfr); ++ ++ buf = &bufs.head->buf; ++ ++ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_bufs_len(&bufs)); ++ ++ CU_ASSERT((ssize_t)nghttp2_bufs_len(&bufs) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ rv = nghttp2_session_mem_recv(session, size_err_hd, sizeof(size_err_hd)); ++ ++ CU_ASSERT((ssize_t)sizeof(size_err_hd) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ nghttp2_session_del(session); ++ ++ /* ALTSVC + on_frame_recv_callback + FRAME_SIZE_ERROR */ ++ memset(&callbacks, 0, sizeof(callbacks)); ++ callbacks.on_frame_recv_callback = term_session_on_frame_recv_callback; ++ ++ nghttp2_session_client_new2(&session, &callbacks, NULL, option); ++ ++ extfr.payload = &altsvc; ++ nghttp2_frame_altsvc_init(&extfr, 0, (uint8_t *)"nghttp2.org", ++ sizeof("nghttp2.org") - 1, (uint8_t *)"h2", ++ sizeof("h2") - 1); ++ nghttp2_bufs_reset(&bufs); ++ nghttp2_frame_pack_altsvc(&bufs, &extfr); ++ ++ buf = &bufs.head->buf; ++ ++ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_bufs_len(&bufs)); ++ ++ CU_ASSERT((ssize_t)nghttp2_bufs_len(&bufs) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ rv = nghttp2_session_mem_recv(session, size_err_hd, sizeof(size_err_hd)); ++ ++ CU_ASSERT((ssize_t)sizeof(size_err_hd) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ nghttp2_session_del(session); ++ ++ /* user-defined extension frame + on_frame_recv_callback + ++ FRAME_SIZE_ERROR */ ++ memset(&callbacks, 0, sizeof(callbacks)); ++ callbacks.on_frame_recv_callback = term_session_on_frame_recv_callback; ++ callbacks.unpack_extension_callback = unpack_extension_callback; ++ ++ nghttp2_session_server_new2(&session, &callbacks, &ud, option); ++ ++ nghttp2_buf_reset(&ud.scratchbuf); ++ ++ rv = nghttp2_session_mem_recv(session, udbuf.pos, nghttp2_buf_len(&udbuf)); ++ ++ CU_ASSERT((ssize_t)nghttp2_buf_len(&udbuf) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ rv = nghttp2_session_mem_recv(session, size_err_hd, sizeof(size_err_hd)); ++ ++ CU_ASSERT((ssize_t)sizeof(size_err_hd) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ nghttp2_session_del(session); ++ ++ /* DATA + on_data_chunk_recv_callback + FRAME_SIZE_ERROR*/ ++ memset(&callbacks, 0, sizeof(callbacks)); ++ callbacks.on_data_chunk_recv_callback = ++ term_session_on_data_chunk_recv_callback; ++ ++ nghttp2_session_server_new(&session, &callbacks, NULL); ++ ++ nvlen = ARRLEN(reqnv); ++ nghttp2_nv_array_copy(&nva, reqnv, nvlen, mem); ++ nghttp2_frame_headers_init(&frame.headers, NGHTTP2_FLAG_END_HEADERS, 1, ++ NGHTTP2_HCAT_HEADERS, NULL, nva, nvlen); ++ nghttp2_hd_deflate_init(&deflater, mem); ++ nghttp2_bufs_reset(&bufs); ++ rv = nghttp2_frame_pack_headers(&bufs, &frame.headers, &deflater); ++ ++ CU_ASSERT(0 == rv); ++ ++ nghttp2_frame_headers_free(&frame.headers, mem); ++ ++ buf = &bufs.head->buf; ++ ++ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_bufs_len(&bufs)); ++ ++ CU_ASSERT((ssize_t)nghttp2_bufs_len(&bufs) == rv); ++ CU_ASSERT(NGHTTP2_IB_READ_HEAD == session->iframe.state); ++ ++ nghttp2_frame_hd_init(&hd, 10, NGHTTP2_DATA, NGHTTP2_FLAG_NONE, 1); ++ nghttp2_bufs_reset(&bufs); ++ nghttp2_frame_pack_frame_hd(bufs.head->buf.last, &hd); ++ bufs.head->buf.last += NGHTTP2_FRAME_HDLEN; ++ memset(bufs.head->buf.last, 0, 10); ++ bufs.head->buf.last += 10; ++ ++ buf = &bufs.head->buf; ++ ++ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_bufs_len(&bufs)); ++ ++ CU_ASSERT((ssize_t)nghttp2_bufs_len(&bufs) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ rv = nghttp2_session_mem_recv(session, size_err_hd, sizeof(size_err_hd)); ++ ++ CU_ASSERT((ssize_t)sizeof(size_err_hd) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ nghttp2_hd_deflate_free(&deflater); ++ nghttp2_session_del(session); ++ ++ /* user-defined extension frame + on_extension_chunk_recv_callback + ++ FRAME_SIZE_ERROR */ ++ memset(&callbacks, 0, sizeof(callbacks)); ++ callbacks.on_extension_chunk_recv_callback = ++ term_session_on_extension_chunk_recv_callback; ++ callbacks.unpack_extension_callback = unpack_extension_callback; ++ ++ nghttp2_session_server_new2(&session, &callbacks, &ud, option); ++ ++ nghttp2_buf_reset(&ud.scratchbuf); ++ ++ rv = nghttp2_session_mem_recv(session, udbuf.pos, nghttp2_buf_len(&udbuf)); ++ ++ CU_ASSERT((ssize_t)nghttp2_buf_len(&udbuf) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ rv = nghttp2_session_mem_recv(session, size_err_hd, sizeof(size_err_hd)); ++ ++ CU_ASSERT((ssize_t)sizeof(size_err_hd) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ nghttp2_session_del(session); ++ ++ /* user-defined extension frame + unpack_extension_callback + ++ FRAME_SIZE_ERROR */ ++ memset(&callbacks, 0, sizeof(callbacks)); ++ callbacks.unpack_extension_callback = term_session_unpack_extension_callback; ++ ++ nghttp2_session_server_new2(&session, &callbacks, &ud, option); ++ ++ nghttp2_buf_reset(&ud.scratchbuf); ++ ++ rv = nghttp2_session_mem_recv(session, udbuf.pos, nghttp2_buf_len(&udbuf)); ++ ++ CU_ASSERT((ssize_t)nghttp2_buf_len(&udbuf) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ rv = nghttp2_session_mem_recv(session, size_err_hd, sizeof(size_err_hd)); ++ ++ CU_ASSERT((ssize_t)sizeof(size_err_hd) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ nghttp2_session_del(session); ++ ++ /* PRIORITY_UPDATE on stream 1 + FRAME_SIZE_ERROR */ ++ memset(&callbacks, 0, sizeof(callbacks)); ++ ++ nghttp2_session_server_new2(&session, &callbacks, NULL, option); ++ ++ session->pending_no_rfc7540_priorities = 1; ++ ++ extfr.payload = &priority_update; ++ nghttp2_frame_priority_update_init(&extfr, 1, (uint8_t *)field_value, ++ sizeof(field_value) - 1); ++ nghttp2_bufs_reset(&bufs); ++ nghttp2_frame_pack_priority_update(&bufs, &extfr); ++ buf = &bufs.head->buf; ++ /* Set invalid stream ID 1 */ ++ buf->pos[5 + sizeof(uint32_t) - 1] = 1; ++ ++ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_bufs_len(&bufs)); ++ ++ CU_ASSERT((ssize_t)nghttp2_bufs_len(&bufs) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ rv = nghttp2_session_mem_recv(session, size_err_hd, sizeof(size_err_hd)); ++ ++ CU_ASSERT((ssize_t)sizeof(size_err_hd) == rv); ++ CU_ASSERT(NGHTTP2_IB_IGN_ALL == session->iframe.state); ++ ++ nghttp2_session_del(session); ++ ++ nghttp2_buf_free(&udbuf, mem); ++ nghttp2_buf_free(&ud.scratchbuf, mem); ++ nghttp2_bufs_free(&bufs); ++ nghttp2_option_del(option); ++} ++ + static void check_nghttp2_http_recv_headers_fail( + nghttp2_session *session, nghttp2_hd_deflater *deflater, int32_t stream_id, + int stream_state, const nghttp2_nv *nva, size_t nvlen) { +--- a/tests/nghttp2_session_test.h ++++ b/tests/nghttp2_session_test.h +@@ -168,6 +168,7 @@ void test_nghttp2_session_no_closed_stre + void test_nghttp2_session_set_stream_user_data(void); + void test_nghttp2_session_no_rfc7540_priorities(void); + void test_nghttp2_session_server_fallback_rfc7540_priorities(void); ++void test_nghttp2_session_verify_iframe_state(void); + void test_nghttp2_session_stream_reset_ratelim(void); + void test_nghttp2_http_mandatory_headers(void); + void test_nghttp2_http_content_length(void); diff -Nru nghttp2-1.52.0/debian/patches/CVE-2026-27135.patch nghttp2-1.52.0/debian/patches/CVE-2026-27135.patch --- nghttp2-1.52.0/debian/patches/CVE-2026-27135.patch 1970-01-01 00:00:00.000000000 +0000 +++ nghttp2-1.52.0/debian/patches/CVE-2026-27135.patch 2026-04-15 14:23:22.000000000 +0000 @@ -0,0 +1,114 @@ +From 5c7df8fa815ac1004d9ecb9d1f7595c4d37f46e1 Mon Sep 17 00:00:00 2001 +From: Tatsuhiro Tsujikawa +Date: Wed, 18 Feb 2026 18:04:30 +0900 +Subject: Fix missing iframe->state validations to avoid assertion failure + +Backported from upstream commit 5c7df8fa815ac1004d9ecb9d1f7595c4d37f46e1. +Uses ssize_t instead of nghttp2_ssize, and targets nghttp2_session_mem_recv +instead of nghttp2_session_mem_recv2. Also, adding an extra hunk, avoiding an +additional assertion, as discovered by the upstream test case. + +Origin: backport, https://github.com/nghttp2/nghttp2/commit/5c7df8f +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1131369 + +--- a/lib/nghttp2_session.c ++++ b/lib/nghttp2_session.c +@@ -6087,6 +6087,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2 + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (ssize_t)inlen; ++ } ++ + on_begin_frame_called = 1; + + rv = session_process_headers_frame(session); +@@ -6453,6 +6457,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2 + if (nghttp2_is_fatal(rv)) { + return rv; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (ssize_t)inlen; ++ } + } + } + +@@ -6709,6 +6717,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2 + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (ssize_t)inlen; ++ } ++ + session_inbound_frame_reset(session); + + break; +@@ -6837,6 +6849,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2 + if (nghttp2_is_fatal(rv)) { + return rv; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (ssize_t)inlen; ++ } + } + session_inbound_frame_reset(session); + +@@ -7012,6 +7028,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2 + if (nghttp2_is_fatal(rv)) { + return rv; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (ssize_t)inlen; ++ } + } else { + iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; + } +@@ -7184,6 +7204,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2 + if (nghttp2_is_fatal(rv)) { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (ssize_t)inlen; ++ } + } + } + } +@@ -7264,6 +7288,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2 + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (ssize_t)inlen; ++ } ++ + if (rv != 0) { + busy = 1; + +@@ -7282,6 +7310,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2 + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (ssize_t)inlen; ++ } ++ + session_inbound_frame_reset(session); + + break; +@@ -7310,6 +7342,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2 + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (ssize_t)inlen; ++ } ++ + session_inbound_frame_reset(session); + + break; diff -Nru nghttp2-1.52.0/debian/patches/series nghttp2-1.52.0/debian/patches/series --- nghttp2-1.52.0/debian/patches/series 2024-09-27 13:25:31.000000000 +0000 +++ nghttp2-1.52.0/debian/patches/series 2026-04-15 14:23:22.000000000 +0000 @@ -3,3 +3,5 @@ CVE-2023-44487.patch 0001-Limit-CONTINUATION-frames-following-an-incoming-HEAD.patch 0002-Add-nghttp2_option_set_max_continuations.patch +CVE-2026-27135.patch +CVE-2026-27135-test.patch