Files
buildroot/package/nghttp2/0001-Fix-missing-iframe-state-validations-to-avoid-assertion-failure.patch
Thomas Perale d75c53a758 package/nghttp2: patch CVE-2026-27135
Fixes the following vulnerability:

- CVE-2026-27135:
    nghttp2 is an implementation of the Hypertext Transfer Protocol
    version 2 in C. Prior to version 1.68.1, the nghttp2 library stops
    reading the incoming data when user facing public API
    `nghttp2_session_terminate_session` or
    `nghttp2_session_terminate_session2` is called by the application.
    They might be called internally by the library when it detects the
    situation that is subject to connection error. Due to the missing
    internal state validation, the library keeps reading the rest of the
    data after one of those APIs is called. Then receiving a malformed
    frame that causes FRAME_SIZE_ERROR causes assertion failure. nghttp2
    v1.68.1 adds missing state validation to avoid assertion failure. No
    known workarounds are available.

For more information, see:
  - https://www.cve.org/CVERecord?id=CVE-2026-27135
  - 5c7df8fa81

(cherry picked from commit 7d26ff6c14)
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
2026-04-10 11:56:10 +02:00

106 lines
3.2 KiB
Diff

From 5c7df8fa815ac1004d9ecb9d1f7595c4d37f46e1 Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Wed, 18 Feb 2026 18:04:30 +0900
Subject: [PATCH] Fix missing iframe->state validations to avoid assertion
failure
CVE: CVE-2026-27135
Upstream: https://github.com/nghttp2/nghttp2/commit/5c7df8fa815ac1004d9ecb9d1f7595c4d37f46e1
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
---
lib/nghttp2_session.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c
index bcea547343..0fbcc930b9 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,
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 (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;