diff --git a/0001-nghttp2-1.68.0-Check-nghttp2_is_fatal-first.patch b/0001-nghttp2-1.68.0-Check-nghttp2_is_fatal-first.patch new file mode 100644 index 0000000..4088026 --- /dev/null +++ b/0001-nghttp2-1.68.0-Check-nghttp2_is_fatal-first.patch @@ -0,0 +1,57 @@ +From 76ff93e618a763501dfa136a8aef16fd7ba51d62 Mon Sep 17 00:00:00 2001 +From: Tatsuhiro Tsujikawa +Date: Wed, 18 Feb 2026 22:40:57 +0900 +Subject: [PATCH 1/2] Check nghttp2_is_fatal first + +(cherry picked from commit 68f77a347544c207eeff7ff7457284697ccf7f7d) +--- + lib/nghttp2_session.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c +index 1f4ea54c..bcea5473 100644 +--- a/lib/nghttp2_session.c ++++ b/lib/nghttp2_session.c +@@ -5466,6 +5466,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + busy = 1; + + rv = session_on_data_received_fail_fast(session); ++ if (nghttp2_is_fatal(rv)) { ++ return rv; ++ } ++ + if (iframe->state == NGHTTP2_IB_IGN_ALL) { + return (nghttp2_ssize)inlen; + } +@@ -5486,10 +5490,6 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + break; + } + +- if (nghttp2_is_fatal(rv)) { +- return rv; +- } +- + rv = inbound_frame_handle_pad(iframe, &iframe->frame.hd); + if (rv < 0) { + rv = nghttp2_session_terminate_session_with_reason( +@@ -6771,13 +6771,13 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + rv = session->callbacks.on_data_chunk_recv_callback( + session, iframe->frame.hd.flags, iframe->frame.hd.stream_id, + in - readlen, (size_t)data_readlen, session->user_data); +- if (rv == NGHTTP2_ERR_PAUSE) { +- return (nghttp2_ssize)(in - first); +- } +- + if (nghttp2_is_fatal(rv)) { + return NGHTTP2_ERR_CALLBACK_FAILURE; + } ++ ++ if (rv == NGHTTP2_ERR_PAUSE) { ++ return (nghttp2_ssize)(in - first); ++ } + } + } + } +-- +2.53.0 + diff --git a/0002-nghttp2-1.68.0-Fix-missing-iframe-state-validations-to-avoid-assert.patch b/0002-nghttp2-1.68.0-Fix-missing-iframe-state-validations-to-avoid-assert.patch new file mode 100644 index 0000000..792102c --- /dev/null +++ b/0002-nghttp2-1.68.0-Fix-missing-iframe-state-validations-to-avoid-assert.patch @@ -0,0 +1,106 @@ +From b21342258a0674686627e98aa2c76e53b2da723b Mon Sep 17 00:00:00 2001 +From: Tatsuhiro Tsujikawa +Date: Wed, 18 Feb 2026 18:04:30 +0900 +Subject: [PATCH 2/2] Fix missing iframe->state validations to avoid assertion + failure + +(cherry picked from commit 5c7df8fa815ac1004d9ecb9d1f7595c4d37f46e1) +--- + lib/nghttp2_session.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c +index bcea5473..0fbcc930 100644 +--- a/lib/nghttp2_session.c ++++ b/lib/nghttp2_session.c +@@ -5573,6 +5573,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + on_begin_frame_called = 1; + + rv = session_process_headers_frame(session); +@@ -6041,6 +6045,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + if (nghttp2_is_fatal(rv)) { + return rv; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } + } + } + +@@ -6293,6 +6301,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + session_inbound_frame_reset(session); + + break; +@@ -6599,6 +6611,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + if (nghttp2_is_fatal(rv)) { + return rv; + } ++ ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } + } else { + iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK; + } +@@ -6775,6 +6791,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + if (rv == NGHTTP2_ERR_PAUSE) { + return (nghttp2_ssize)(in - first); + } +@@ -6861,6 +6881,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + if (rv != 0) { + busy = 1; + +@@ -6879,6 +6903,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + session_inbound_frame_reset(session); + + break; +@@ -6907,6 +6935,10 @@ nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session, + return rv; + } + ++ if (iframe->state == NGHTTP2_IB_IGN_ALL) { ++ return (nghttp2_ssize)inlen; ++ } ++ + session_inbound_frame_reset(session); + + break; +-- +2.53.0 + diff --git a/nghttp2.spec b/nghttp2.spec index 8d733da..7f37939 100644 --- a/nghttp2.spec +++ b/nghttp2.spec @@ -7,7 +7,7 @@ Summary: Experimental HTTP/2 client, server and proxy Name: nghttp2 Version: 1.68.0 -Release: 3%{?dist} +Release: 4%{?dist} # Parts of ruby bindings are additionally under GPL-2.0-or-later, MIT and # HPND-Kevlin-Henney but they are NOT shipped. @@ -18,6 +18,10 @@ Source0: https://github.com/tatsuhiro-t/nghttp2/releases/download/v%{version}/ng Source1: https://github.com/%{name}/%{name}/releases/download/v%{version}/%{name}-%{version}.tar.xz.asc Source2: tatsuhiro-t.pgp +# fix Denial of service: Assertion failure due to the missing state validation (CVE-2026-27135) +Patch001: 0001-nghttp2-1.68.0-Check-nghttp2_is_fatal-first.patch +Patch002: 0002-nghttp2-1.68.0-Fix-missing-iframe-state-validations-to-avoid-assert.patch + # Make X25519MLKEM768 the default TLS key exchange group in nghttpd and nghttpx # https://issues.redhat.com/browse/RHEL-103655 Patch100: 0100-nghttp2-1.64.0-pqc-add-X25519MLKEM768-as-the-default-TLS-key-exchan.patch @@ -213,6 +217,9 @@ popd %changelog +* Tue Mar 31 2026 Jan Macku 1.68.0-4 +- fix Denial of service: Assertion failure due to the missing state validation (CVE-2026-27135) + * Wed Feb 11 2026 Jan Macku 1.68.0-3 - Spec bump (RHEL-103655)