Bug#1082902: bookworm-pu: package nghttp2/1.52.0-1+deb12u2
Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: security@debian.org, Tomasz Buchert <tomasz@debian.org>
* CVE-2024-28182: unbounded number of HTTP/2 CONTINUATION frames DoS
(Closes: #1068415)
* nghttp2_option_set_stream_reset_rate_limit was added in
1.52.0-1+deb12u1, add to debian/libnghttp2-14.symbols
Tagged moreinfo, as question to the security team whether they want
this in -pu or as DSA.
diffstat for nghttp2-1.52.0 nghttp2-1.52.0
changelog | 10
libnghttp2-14.symbols | 2
patches/0001-Limit-CONTINUATION-frames-following-an-incoming-HEAD.patch | 106 ++++++++++
patches/0002-Add-nghttp2_option_set_max_continuations.patch | 101 +++++++++
patches/series | 2
5 files changed, 221 insertions(+)
diff -Nru nghttp2-1.52.0/debian/changelog nghttp2-1.52.0/debian/changelog
--- nghttp2-1.52.0/debian/changelog 2023-11-24 16:57:26.000000000 +0200
+++ nghttp2-1.52.0/debian/changelog 2024-09-27 16:25:38.000000000 +0300
@@ -1,3 +1,13 @@
+nghttp2 (1.52.0-1+deb12u2) bookworm; urgency=medium
+
+ * Non-maintainer upload.
+ * CVE-2024-28182: unbounded number of HTTP/2 CONTINUATION frames DoS
+ (Closes: #1068415)
+ * nghttp2_option_set_stream_reset_rate_limit was added in
+ 1.52.0-1+deb12u1, add to debian/libnghttp2-14.symbols
+
+ -- Adrian Bunk <bunk@debian.org> Fri, 27 Sep 2024 16:25:38 +0300
+
nghttp2 (1.52.0-1+deb12u1) bookworm-security; urgency=medium
* CVE-2023-44487 (Closes: #1053769)
diff -Nru nghttp2-1.52.0/debian/libnghttp2-14.symbols nghttp2-1.52.0/debian/libnghttp2-14.symbols
--- nghttp2-1.52.0/debian/libnghttp2-14.symbols 2022-09-25 17:26:28.000000000 +0300
+++ nghttp2-1.52.0/debian/libnghttp2-14.symbols 2024-09-27 16:25:38.000000000 +0300
@@ -33,6 +33,7 @@
nghttp2_option_del@Base 1.3.0
nghttp2_option_new@Base 1.3.0
nghttp2_option_set_builtin_recv_extension_type@Base 1.10.0
+ nghttp2_option_set_max_continuations@Base 1.52.0-1+deb12u2~
nghttp2_option_set_max_deflate_dynamic_table_size@Base 1.15.0
nghttp2_option_set_max_outbound_ack@Base 1.39.2
nghttp2_option_set_max_reserved_remote_streams@Base 1.3.0
@@ -46,6 +47,7 @@
nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation@Base 1.50.0
nghttp2_option_set_peer_max_concurrent_streams@Base 1.3.0
nghttp2_option_set_server_fallback_rfc7540_priorities@Base 1.48.0
+ nghttp2_option_set_stream_reset_rate_limit@Base 1.52.0-1+deb12u1~
nghttp2_option_set_user_recv_extension_type@Base 1.8.0
nghttp2_pack_settings_payload@Base 1.3.0
nghttp2_priority_spec_check_default@Base 1.3.0
diff -Nru nghttp2-1.52.0/debian/patches/0001-Limit-CONTINUATION-frames-following-an-incoming-HEAD.patch nghttp2-1.52.0/debian/patches/0001-Limit-CONTINUATION-frames-following-an-incoming-HEAD.patch
--- nghttp2-1.52.0/debian/patches/0001-Limit-CONTINUATION-frames-following-an-incoming-HEAD.patch 1970-01-01 02:00:00.000000000 +0200
+++ nghttp2-1.52.0/debian/patches/0001-Limit-CONTINUATION-frames-following-an-incoming-HEAD.patch 2024-09-27 16:21:17.000000000 +0300
@@ -0,0 +1,106 @@
+From 73d22aa3debd47d8b87a256f3262f84d08ece9ca Mon Sep 17 00:00:00 2001
+From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+Date: Sat, 9 Mar 2024 16:26:42 +0900
+Subject: Limit CONTINUATION frames following an incoming HEADER frame
+
+---
+ lib/includes/nghttp2/nghttp2.h | 7 ++++++-
+ lib/nghttp2_helper.c | 2 ++
+ lib/nghttp2_session.c | 7 +++++++
+ lib/nghttp2_session.h | 10 ++++++++++
+ 4 files changed, 25 insertions(+), 1 deletion(-)
+
+diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h
+index fa22081c..b394bde9 100644
+--- a/lib/includes/nghttp2/nghttp2.h
++++ b/lib/includes/nghttp2/nghttp2.h
+@@ -440,7 +440,12 @@ typedef enum {
+ * exhaustion on server side to send these frames forever and does
+ * not read network.
+ */
+- NGHTTP2_ERR_FLOODED = -904
++ NGHTTP2_ERR_FLOODED = -904,
++ /**
++ * When a local endpoint receives too many CONTINUATION frames
++ * following a HEADER frame.
++ */
++ NGHTTP2_ERR_TOO_MANY_CONTINUATIONS = -905,
+ } nghttp2_error;
+
+ /**
+diff --git a/lib/nghttp2_helper.c b/lib/nghttp2_helper.c
+index 93dd4754..b3563d98 100644
+--- a/lib/nghttp2_helper.c
++++ b/lib/nghttp2_helper.c
+@@ -336,6 +336,8 @@ const char *nghttp2_strerror(int error_code) {
+ "closed";
+ case NGHTTP2_ERR_TOO_MANY_SETTINGS:
+ return "SETTINGS frame contained more than the maximum allowed entries";
++ case NGHTTP2_ERR_TOO_MANY_CONTINUATIONS:
++ return "Too many CONTINUATION frames following a HEADER frame";
+ default:
+ return "Unknown error code";
+ }
+diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c
+index 80f10baa..47f5150e 100644
+--- a/lib/nghttp2_session.c
++++ b/lib/nghttp2_session.c
+@@ -496,6 +496,7 @@ static int session_new(nghttp2_session **session_ptr,
+ (*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN;
+ (*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM;
+ (*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS;
++ (*session_ptr)->max_continuations = NGHTTP2_DEFAULT_MAX_CONTINUATIONS;
+
+ if (option) {
+ if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) &&
+@@ -6867,6 +6868,8 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
+ }
+ }
+ session_inbound_frame_reset(session);
++
++ session->num_continuations = 0;
+ }
+ break;
+ }
+@@ -6988,6 +6991,10 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
+ }
+ #endif /* DEBUGBUILD */
+
++ if (++session->num_continuations > session->max_continuations) {
++ return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS;
++ }
++
+ readlen = inbound_frame_buf_read(iframe, in, last);
+ in += readlen;
+
+diff --git a/lib/nghttp2_session.h b/lib/nghttp2_session.h
+index b119329a..ef8f7b27 100644
+--- a/lib/nghttp2_session.h
++++ b/lib/nghttp2_session.h
+@@ -110,6 +110,10 @@ typedef struct {
+ #define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
+ #define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
+
++/* The default max number of CONTINUATION frames following an incoming
++ HEADER frame. */
++#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8
++
+ /* Internal state when receiving incoming frame */
+ typedef enum {
+ /* Receiving frame header */
+@@ -290,6 +294,12 @@ struct nghttp2_session {
+ size_t max_send_header_block_length;
+ /* The maximum number of settings accepted per SETTINGS frame. */
+ size_t max_settings;
++ /* The maximum number of CONTINUATION frames following an incoming
++ HEADER frame. */
++ size_t max_continuations;
++ /* The number of CONTINUATION frames following an incoming HEADER
++ frame. This variable is reset when END_HEADERS flag is seen. */
++ size_t num_continuations;
+ /* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
+ uint32_t next_stream_id;
+ /* The last stream ID this session initiated. For client session,
+--
+2.30.2
+
diff -Nru nghttp2-1.52.0/debian/patches/0002-Add-nghttp2_option_set_max_continuations.patch nghttp2-1.52.0/debian/patches/0002-Add-nghttp2_option_set_max_continuations.patch
--- nghttp2-1.52.0/debian/patches/0002-Add-nghttp2_option_set_max_continuations.patch 1970-01-01 02:00:00.000000000 +0200
+++ nghttp2-1.52.0/debian/patches/0002-Add-nghttp2_option_set_max_continuations.patch 2024-09-27 16:21:17.000000000 +0300
@@ -0,0 +1,101 @@
+From 9fb1035594880ff572940d443de4b40fdff3e365 Mon Sep 17 00:00:00 2001
+From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
+Date: Sat, 9 Mar 2024 16:48:10 +0900
+Subject: Add nghttp2_option_set_max_continuations
+
+---
+ doc/Makefile.am | 1 +
+ lib/includes/nghttp2/nghttp2.h | 11 +++++++++++
+ lib/nghttp2_option.c | 5 +++++
+ lib/nghttp2_option.h | 5 +++++
+ lib/nghttp2_session.c | 4 ++++
+ 5 files changed, 26 insertions(+)
+
+diff --git a/doc/Makefile.am b/doc/Makefile.am
+index 96f449ff..5636a137 100644
+--- a/doc/Makefile.am
++++ b/doc/Makefile.am
+@@ -73,6 +73,7 @@ APIDOCS= \
+ nghttp2_option_set_peer_max_concurrent_streams.rst \
+ nghttp2_option_set_server_fallback_rfc7540_priorities.rst \
+ nghttp2_option_set_user_recv_extension_type.rst \
++ nghttp2_option_set_max_continuations.rst \
+ nghttp2_option_set_max_outbound_ack.rst \
+ nghttp2_option_set_max_settings.rst \
+ nghttp2_option_set_stream_reset_rate_limit.rst \
+diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h
+index b394bde9..4d3339b5 100644
+--- a/lib/includes/nghttp2/nghttp2.h
++++ b/lib/includes/nghttp2/nghttp2.h
+@@ -2778,6 +2778,17 @@ NGHTTP2_EXTERN void
+ nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
+ uint64_t burst, uint64_t rate);
+
++/**
++ * @function
++ *
++ * This function sets the maximum number of CONTINUATION frames
++ * following an incoming HEADER frame. If more than those frames are
++ * received, the remote endpoint is considered to be misbehaving and
++ * session will be closed. The default value is 8.
++ */
++NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option,
++ size_t val);
++
+ /**
+ * @function
+ *
+diff --git a/lib/nghttp2_option.c b/lib/nghttp2_option.c
+index 43d4e952..53144b9b 100644
+--- a/lib/nghttp2_option.c
++++ b/lib/nghttp2_option.c
+@@ -150,3 +150,8 @@ void nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
+ option->stream_reset_burst = burst;
+ option->stream_reset_rate = rate;
+ }
++
++void nghttp2_option_set_max_continuations(nghttp2_option *option, size_t val) {
++ option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS;
++ option->max_continuations = val;
++}
+diff --git a/lib/nghttp2_option.h b/lib/nghttp2_option.h
+index 2259e184..c89cb97f 100644
+--- a/lib/nghttp2_option.h
++++ b/lib/nghttp2_option.h
+@@ -71,6 +71,7 @@ typedef enum {
+ NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 13,
+ NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14,
+ NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15,
++ NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16,
+ } nghttp2_option_flag;
+
+ /**
+@@ -98,6 +99,10 @@ struct nghttp2_option {
+ * NGHTTP2_OPT_MAX_SETTINGS
+ */
+ size_t max_settings;
++ /**
++ * NGHTTP2_OPT_MAX_CONTINUATIONS
++ */
++ size_t max_continuations;
+ /**
+ * Bitwise OR of nghttp2_option_flag to determine that which fields
+ * are specified.
+diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c
+index 47f5150e..92425b15 100644
+--- a/lib/nghttp2_session.c
++++ b/lib/nghttp2_session.c
+@@ -585,6 +585,10 @@ static int session_new(nghttp2_session **session_ptr,
+ option->stream_reset_burst,
+ option->stream_reset_rate);
+ }
++
++ if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) {
++ (*session_ptr)->max_continuations = option->max_continuations;
++ }
+ }
+
+ rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
+--
+2.30.2
+
diff -Nru nghttp2-1.52.0/debian/patches/series nghttp2-1.52.0/debian/patches/series
--- nghttp2-1.52.0/debian/patches/series 2023-11-24 16:57:26.000000000 +0200
+++ nghttp2-1.52.0/debian/patches/series 2024-09-27 16:25:31.000000000 +0300
@@ -1,3 +1,5 @@
0001-Make-fetch-ocsp-response-use-python3.patch
0002-Workaround-for-963648.patch
CVE-2023-44487.patch
+0001-Limit-CONTINUATION-frames-following-an-incoming-HEAD.patch
+0002-Add-nghttp2_option_set_max_continuations.patch
Reply to: