diff --git a/backport-CVE-2023-44487.patch b/backport-CVE-2023-44487.patch deleted file mode 100644 index 133a420c23ce35240ac8dfa9975fba9779a06177..0000000000000000000000000000000000000000 --- a/backport-CVE-2023-44487.patch +++ /dev/null @@ -1,976 +0,0 @@ -From c847a536f1f2f3ea373ccfbda8178146e44137a4 Mon Sep 17 00:00:00 2001 -From: Tatsuhiro Tsujikawa -Date: Sun, 1 Oct 2023 00:05:01 +0900 -Subject: [PATCH] Rework session management - -Conflict: remove .github/workflows/build.yml -Reference: https://github.com/nghttp2/nghttp2/commit/72b4af6143681f528f1d237b21a9a7aee1738832 - ---- - CMakeLists.txt | 4 ++ - cmakeconfig.h.in | 9 +++ - configure.ac | 21 +++++++ - doc/Makefile.am | 1 + - lib/CMakeLists.txt | 2 + - lib/Makefile.am | 4 ++ - lib/includes/nghttp2/nghttp2.h | 17 ++++++ - lib/nghttp2_option.c | 7 +++ - lib/nghttp2_option.h | 6 ++ - lib/nghttp2_ratelim.c | 75 ++++++++++++++++++++++++ - lib/nghttp2_ratelim.h | 57 ++++++++++++++++++ - lib/nghttp2_session.c | 34 ++++++++++- - lib/nghttp2_session.h | 12 +++- - lib/nghttp2_time.c | 62 ++++++++++++++++++++ - lib/nghttp2_time.h | 38 ++++++++++++ - tests/CMakeLists.txt | 1 + - tests/Makefile.am | 6 +- - tests/main.c | 7 ++- - tests/nghttp2_ratelim_test.c | 101 ++++++++++++++++++++++++++++++++ - tests/nghttp2_ratelim_test.h | 35 +++++++++++ - tests/nghttp2_session_test.c | 103 +++++++++++++++++++++++++++++++++ - tests/nghttp2_session_test.h | 1 + - 22 files changed, 598 insertions(+), 5 deletions(-) - create mode 100644 lib/nghttp2_ratelim.c - create mode 100644 lib/nghttp2_ratelim.h - create mode 100644 lib/nghttp2_time.c - create mode 100644 lib/nghttp2_time.h - create mode 100644 tests/nghttp2_ratelim_test.c - create mode 100644 tests/nghttp2_ratelim_test.h - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 3f7ec67b..ceab1164 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -276,6 +276,7 @@ check_include_file("netinet/in.h" HAVE_NETINET_IN_H) - check_include_file("pwd.h" HAVE_PWD_H) - check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H) - check_include_file("sys/time.h" HAVE_SYS_TIME_H) -+check_include_file("sysinfoapi.h" HAVE_SYSINFOAPI_H) - check_include_file("syslog.h" HAVE_SYSLOG_H) - check_include_file("time.h" HAVE_TIME_H) - check_include_file("unistd.h" HAVE_UNISTD_H) -@@ -316,8 +317,11 @@ check_type_size("time_t" SIZEOF_TIME_T) - include(CheckFunctionExists) - check_function_exists(_Exit HAVE__EXIT) - check_function_exists(accept4 HAVE_ACCEPT4) -+check_function_exists(clock_gettime HAVE_CLOCK_GETTIME) - check_function_exists(mkostemp HAVE_MKOSTEMP) - -+check_symbol_exists(GetTickCount64 sysinfoapi.h HAVE_GETTICKCOUNT64) -+ - include(CheckSymbolExists) - # XXX does this correctly detect initgroups (un)availability on cygwin? - check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS) -diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in -index 49d19a31..6f596bf6 100644 ---- a/cmakeconfig.h.in -+++ b/cmakeconfig.h.in -@@ -31,9 +31,15 @@ - /* Define to 1 if you have the `accept4` function. */ - #cmakedefine HAVE_ACCEPT4 1 - -+/* Define to 1 if you have the `clock_gettime` function. */ -+#cmakedefine HAVE_CLOCK_GETTIME 1 -+ - /* Define to 1 if you have the `mkostemp` function. */ - #cmakedefine HAVE_MKOSTEMP 1 - -+/* Define to 1 if you have the `GetTickCount64` function. */ -+#cmakedefine HAVE_GETTICKCOUNT64 1 -+ - /* Define to 1 if you have the `initgroups` function. */ - #cmakedefine01 HAVE_DECL_INITGROUPS - -@@ -70,6 +76,9 @@ - /* Define to 1 if you have the header file. */ - #cmakedefine HAVE_SYS_TIME_H 1 - -+/* Define to 1 if you have the header file. */ -+#cmakedefine HAVE_SYSINFOAPI_H 1 -+ - /* Define to 1 if you have the header file. */ - #cmakedefine HAVE_SYSLOG_H 1 - -diff --git a/configure.ac b/configure.ac -index 5163b03c..fc17e126 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -854,6 +854,7 @@ AC_CHECK_HEADERS([ \ - string.h \ - sys/socket.h \ - sys/time.h \ -+ sysinfoapi.h \ - syslog.h \ - time.h \ - unistd.h \ -@@ -928,6 +929,7 @@ AC_FUNC_STRNLEN - AC_CHECK_FUNCS([ \ - _Exit \ - accept4 \ -+ clock_gettime \ - dup2 \ - getcwd \ - getpwnam \ -@@ -953,6 +955,25 @@ AC_CHECK_FUNCS([ \ - AC_CHECK_FUNC([timerfd_create], - [have_timerfd_create=yes], [have_timerfd_create=no]) - -+AC_MSG_CHECKING([checking for GetTickCount64]) -+AC_LINK_IFELSE([AC_LANG_PROGRAM( -+[[ -+#include -+]], -+[[ -+GetTickCount64(); -+]])], -+[have_gettickcount64=yes], -+[have_gettickcount64=no]) -+ -+if test "x${have_gettickcount64}" = "xyes"; then -+ AC_MSG_RESULT([yes]) -+ AC_DEFINE([HAVE_GETTICKCOUNT64], [1], -+ [Define to 1 if you have `GetTickCount64` function.]) -+else -+ AC_MSG_RESULT([no]) -+fi -+ - # For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but - # cygwin disables initgroups due to feature test macro magic with our - # configuration. FreeBSD declares initgroups() in unistd.h. -diff --git a/doc/Makefile.am b/doc/Makefile.am -index 53f63c36..96f449ff 100644 ---- a/doc/Makefile.am -+++ b/doc/Makefile.am -@@ -75,6 +75,7 @@ APIDOCS= \ - nghttp2_option_set_user_recv_extension_type.rst \ - nghttp2_option_set_max_outbound_ack.rst \ - nghttp2_option_set_max_settings.rst \ -+ nghttp2_option_set_stream_reset_rate_limit.rst \ - nghttp2_pack_settings_payload.rst \ - nghttp2_priority_spec_check_default.rst \ - nghttp2_priority_spec_default_init.rst \ -diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt -index fad04716..7adba3a3 100644 ---- a/lib/CMakeLists.txt -+++ b/lib/CMakeLists.txt -@@ -24,6 +24,8 @@ set(NGHTTP2_SOURCES - nghttp2_http.c - nghttp2_rcbuf.c - nghttp2_extpri.c -+ nghttp2_ratelim.c -+ nghttp2_time.c - nghttp2_debug.c - sfparse.c - ) -diff --git a/lib/Makefile.am b/lib/Makefile.am -index cd928ae4..c3ace402 100644 ---- a/lib/Makefile.am -+++ b/lib/Makefile.am -@@ -51,6 +51,8 @@ OBJECTS = nghttp2_pq.c nghttp2_map.c nghttp2_queue.c \ - nghttp2_http.c \ - nghttp2_rcbuf.c \ - nghttp2_extpri.c \ -+ nghttp2_ratelim.c \ -+ nghttp2_time.c \ - nghttp2_debug.c \ - sfparse.c - -@@ -69,6 +71,8 @@ HFILES = nghttp2_pq.h nghttp2_int.h nghttp2_map.h nghttp2_queue.h \ - nghttp2_http.h \ - nghttp2_rcbuf.h \ - nghttp2_extpri.h \ -+ nghttp2_ratelim.h \ -+ nghttp2_time.h \ - nghttp2_debug.h \ - sfparse.h - -diff --git a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h -index 65077dd5..fa22081c 100644 ---- a/lib/includes/nghttp2/nghttp2.h -+++ b/lib/includes/nghttp2/nghttp2.h -@@ -2756,6 +2756,23 @@ NGHTTP2_EXTERN void - nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation( - nghttp2_option *option, int val); - -+/** -+ * @function -+ * -+ * This function sets the rate limit for the incoming stream reset -+ * (RST_STREAM frame). It is server use only. It is a token-bucket -+ * based rate limiter. |burst| specifies the number of tokens that is -+ * initially available. The maximum number of tokens is capped to -+ * this value. |rate| specifies the number of tokens that are -+ * regenerated per second. An incoming RST_STREAM consumes one token. -+ * If there is no token available, GOAWAY is sent to tear down the -+ * connection. |burst| and |rate| default to 1000 and 33 -+ * respectively. -+ */ -+NGHTTP2_EXTERN void -+nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, -+ uint64_t burst, uint64_t rate); -+ - /** - * @function - * -diff --git a/lib/nghttp2_option.c b/lib/nghttp2_option.c -index ee0cd0f0..43d4e952 100644 ---- a/lib/nghttp2_option.c -+++ b/lib/nghttp2_option.c -@@ -143,3 +143,10 @@ void nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation( - NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; - option->no_rfc9113_leading_and_trailing_ws_validation = val; - } -+ -+void nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option, -+ uint64_t burst, uint64_t rate) { -+ option->opt_set_mask |= NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT; -+ option->stream_reset_burst = burst; -+ option->stream_reset_rate = rate; -+} -diff --git a/lib/nghttp2_option.h b/lib/nghttp2_option.h -index b228a075..2259e184 100644 ---- a/lib/nghttp2_option.h -+++ b/lib/nghttp2_option.h -@@ -70,12 +70,18 @@ typedef enum { - NGHTTP2_OPT_MAX_SETTINGS = 1 << 12, - 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_option_flag; - - /** - * Struct to store option values for nghttp2_session. - */ - struct nghttp2_option { -+ /** -+ * NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT -+ */ -+ uint64_t stream_reset_burst; -+ uint64_t stream_reset_rate; - /** - * NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH - */ -diff --git a/lib/nghttp2_ratelim.c b/lib/nghttp2_ratelim.c -new file mode 100644 -index 00000000..7011655b ---- /dev/null -+++ b/lib/nghttp2_ratelim.c -@@ -0,0 +1,75 @@ -+/* -+ * nghttp2 - HTTP/2 C Library -+ * -+ * Copyright (c) 2023 nghttp2 contributors -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sublicense, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#include "nghttp2_ratelim.h" -+#include "nghttp2_helper.h" -+ -+void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate) { -+ rl->val = rl->burst = burst; -+ rl->rate = rate; -+ rl->tstamp = 0; -+} -+ -+void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp) { -+ uint64_t d, gain; -+ -+ if (tstamp == rl->tstamp) { -+ return; -+ } -+ -+ if (tstamp > rl->tstamp) { -+ d = tstamp - rl->tstamp; -+ } else { -+ d = 1; -+ } -+ -+ rl->tstamp = tstamp; -+ -+ if (UINT64_MAX / d < rl->rate) { -+ rl->val = rl->burst; -+ -+ return; -+ } -+ -+ gain = rl->rate * d; -+ -+ if (UINT64_MAX - gain < rl->val) { -+ rl->val = rl->burst; -+ -+ return; -+ } -+ -+ rl->val += gain; -+ rl->val = nghttp2_min(rl->val, rl->burst); -+} -+ -+int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n) { -+ if (rl->val < n) { -+ return -1; -+ } -+ -+ rl->val -= n; -+ -+ return 0; -+} -diff --git a/lib/nghttp2_ratelim.h b/lib/nghttp2_ratelim.h -new file mode 100644 -index 00000000..866ed3f0 ---- /dev/null -+++ b/lib/nghttp2_ratelim.h -@@ -0,0 +1,57 @@ -+/* -+ * nghttp2 - HTTP/2 C Library -+ * -+ * Copyright (c) 2023 nghttp2 contributors -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sublicense, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef NGHTTP2_RATELIM_H -+#define NGHTTP2_RATELIM_H -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif /* HAVE_CONFIG_H */ -+ -+#include -+ -+typedef struct nghttp2_ratelim { -+ /* burst is the maximum value of val. */ -+ uint64_t burst; -+ /* rate is the amount of value that is regenerated per 1 tstamp. */ -+ uint64_t rate; -+ /* val is the amount of value available to drain. */ -+ uint64_t val; -+ /* tstamp is the last timestamp in second resolution that is known -+ to this object. */ -+ uint64_t tstamp; -+} nghttp2_ratelim; -+ -+/* nghttp2_ratelim_init initializes |rl| with the given parameters. */ -+void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate); -+ -+/* nghttp2_ratelim_update updates rl->val with the current |tstamp| -+ given in second resolution. */ -+void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp); -+ -+/* nghttp2_ratelim_drain drains |n| from rl->val. It returns 0 if it -+ succeeds, or -1. */ -+int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n); -+ -+#endif /* NGHTTP2_RATELIM_H */ -diff --git a/lib/nghttp2_session.c b/lib/nghttp2_session.c -index 71858a39..c1ba0404 100644 ---- a/lib/nghttp2_session.c -+++ b/lib/nghttp2_session.c -@@ -37,6 +37,7 @@ - #include "nghttp2_http.h" - #include "nghttp2_pq.h" - #include "nghttp2_extpri.h" -+#include "nghttp2_time.h" - #include "nghttp2_debug.h" - - /* -@@ -475,6 +476,10 @@ static int session_new(nghttp2_session **session_ptr, - (*session_ptr)->pending_enable_push = 1; - (*session_ptr)->pending_no_rfc7540_priorities = UINT8_MAX; - -+ nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim, -+ NGHTTP2_DEFAULT_STREAM_RESET_BURST, -+ NGHTTP2_DEFAULT_STREAM_RESET_RATE); -+ - if (server) { - (*session_ptr)->server = 1; - } -@@ -573,6 +578,12 @@ static int session_new(nghttp2_session **session_ptr, - (*session_ptr)->opt_flags |= - NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION; - } -+ -+ if (option->opt_set_mask & NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT) { -+ nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim, -+ option->stream_reset_burst, -+ option->stream_reset_rate); -+ } - } - - rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater, -@@ -4528,6 +4539,23 @@ static int session_process_priority_frame(nghttp2_session *session) { - return nghttp2_session_on_priority_received(session, frame); - } - -+static int session_update_stream_reset_ratelim(nghttp2_session *session) { -+ if (!session->server || (session->goaway_flags & NGHTTP2_GOAWAY_SUBMITTED)) { -+ return 0; -+ } -+ -+ nghttp2_ratelim_update(&session->stream_reset_ratelim, -+ nghttp2_time_now_sec()); -+ -+ if (nghttp2_ratelim_drain(&session->stream_reset_ratelim, 1) == 0) { -+ return 0; -+ } -+ -+ return nghttp2_session_add_goaway(session, session->last_recv_stream_id, -+ NGHTTP2_INTERNAL_ERROR, NULL, 0, -+ NGHTTP2_GOAWAY_AUX_NONE); -+} -+ - int nghttp2_session_on_rst_stream_received(nghttp2_session *session, - nghttp2_frame *frame) { - int rv; -@@ -4557,7 +4585,8 @@ int nghttp2_session_on_rst_stream_received(nghttp2_session *session, - if (nghttp2_is_fatal(rv)) { - return rv; - } -- return 0; -+ -+ return session_update_stream_reset_ratelim(session); - } - - static int session_process_rst_stream_frame(nghttp2_session *session) { -@@ -7519,6 +7548,9 @@ int nghttp2_session_add_goaway(nghttp2_session *session, int32_t last_stream_id, - nghttp2_mem_free(mem, item); - return rv; - } -+ -+ session->goaway_flags |= NGHTTP2_GOAWAY_SUBMITTED; -+ - return 0; - } - -diff --git a/lib/nghttp2_session.h b/lib/nghttp2_session.h -index 34d2d585..b119329a 100644 ---- a/lib/nghttp2_session.h -+++ b/lib/nghttp2_session.h -@@ -39,6 +39,7 @@ - #include "nghttp2_buf.h" - #include "nghttp2_callbacks.h" - #include "nghttp2_mem.h" -+#include "nghttp2_ratelim.h" - - /* The global variable for tests where we want to disable strict - preface handling. */ -@@ -105,6 +106,10 @@ typedef struct { - /* The default value of maximum number of concurrent streams. */ - #define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu - -+/* The default values for stream reset rate limiter. */ -+#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000 -+#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33 -+ - /* Internal state when receiving incoming frame */ - typedef enum { - /* Receiving frame header */ -@@ -178,7 +183,9 @@ typedef enum { - /* Flag means GOAWAY was sent */ - NGHTTP2_GOAWAY_SENT = 0x4, - /* Flag means GOAWAY was received */ -- NGHTTP2_GOAWAY_RECV = 0x8 -+ NGHTTP2_GOAWAY_RECV = 0x8, -+ /* Flag means GOAWAY has been submitted at least once */ -+ NGHTTP2_GOAWAY_SUBMITTED = 0x10 - } nghttp2_goaway_flag; - - /* nghttp2_inflight_settings stores the SETTINGS entries which local -@@ -235,6 +242,9 @@ struct nghttp2_session { - /* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not - considered as in-flight. */ - nghttp2_inflight_settings *inflight_settings_head; -+ /* Stream reset rate limiter. If receiving excessive amount of -+ stream resets, GOAWAY will be sent. */ -+ nghttp2_ratelim stream_reset_ratelim; - /* Sequential number across all streams to process streams in - FIFO. */ - uint64_t stream_seq; -diff --git a/lib/nghttp2_time.c b/lib/nghttp2_time.c -new file mode 100644 -index 00000000..2a5f1a6f ---- /dev/null -+++ b/lib/nghttp2_time.c -@@ -0,0 +1,62 @@ -+/* -+ * nghttp2 - HTTP/2 C Library -+ * -+ * Copyright (c) 2023 nghttp2 contributors -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sublicense, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#include "nghttp2_time.h" -+ -+#ifdef HAVE_TIME_H -+# include -+#endif /* HAVE_TIME_H */ -+ -+#ifdef HAVE_SYSINFOAPI_H -+# include -+#endif /* HAVE_SYSINFOAPI_H */ -+ -+#ifndef HAVE_GETTICKCOUNT64 -+static uint64_t time_now_sec(void) { -+ time_t t = time(NULL); -+ -+ if (t == -1) { -+ return 0; -+ } -+ -+ return (uint64_t)t; -+} -+#endif /* HAVE_GETTICKCOUNT64 */ -+ -+#ifdef HAVE_CLOCK_GETTIME -+uint64_t nghttp2_time_now_sec(void) { -+ struct timespec tp; -+ int rv = clock_gettime(CLOCK_MONOTONIC, &tp); -+ -+ if (rv == -1) { -+ return time_now_sec(); -+ } -+ -+ return (uint64_t)tp.tv_sec; -+} -+#elif defined(HAVE_GETTICKCOUNT64) -+uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; } -+#else /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */ -+uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); } -+#endif /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */ -diff --git a/lib/nghttp2_time.h b/lib/nghttp2_time.h -new file mode 100644 -index 00000000..03c0bbe9 ---- /dev/null -+++ b/lib/nghttp2_time.h -@@ -0,0 +1,38 @@ -+/* -+ * nghttp2 - HTTP/2 C Library -+ * -+ * Copyright (c) 2023 nghttp2 contributors -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sublicense, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef NGHTTP2_TIME_H -+#define NGHTTP2_TIME_H -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif /* HAVE_CONFIG_H */ -+ -+#include -+ -+/* nghttp2_time_now_sec returns seconds from implementation-specific -+ timepoint. If it is unable to get seconds, it returns 0. */ -+uint64_t nghttp2_time_now_sec(void); -+ -+#endif /* NGHTTP2_TIME_H */ -diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt -index e8a5adbd..0e05235e 100644 ---- a/tests/CMakeLists.txt -+++ b/tests/CMakeLists.txt -@@ -22,6 +22,7 @@ if(HAVE_CUNIT) - nghttp2_buf_test.c - nghttp2_http_test.c - nghttp2_extpri_test.c -+ nghttp2_ratelim_test.c - ) - - add_executable(main EXCLUDE_FROM_ALL -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 162e082e..98d72b6e 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -42,7 +42,8 @@ OBJECTS = main.c nghttp2_pq_test.c nghttp2_map_test.c nghttp2_queue_test.c \ - nghttp2_helper_test.c \ - nghttp2_buf_test.c \ - nghttp2_http_test.c \ -- nghttp2_extpri_test.c -+ nghttp2_extpri_test.c \ -+ nghttp2_ratelim_test.c - - HFILES = nghttp2_pq_test.h nghttp2_map_test.h nghttp2_queue_test.h \ - nghttp2_session_test.h \ -@@ -51,7 +52,8 @@ HFILES = nghttp2_pq_test.h nghttp2_map_test.h nghttp2_queue_test.h \ - nghttp2_test_helper.h \ - nghttp2_buf_test.h \ - nghttp2_http_test.h \ -- nghttp2_extpri_test.h -+ nghttp2_extpri_test.h \ -+ nghttp2_ratelim_test.h - - main_SOURCES = $(HFILES) $(OBJECTS) - -diff --git a/tests/main.c b/tests/main.c -index 590f059b..fc3c28d1 100644 ---- a/tests/main.c -+++ b/tests/main.c -@@ -42,6 +42,7 @@ - #include "nghttp2_buf_test.h" - #include "nghttp2_http_test.h" - #include "nghttp2_extpri_test.h" -+#include "nghttp2_ratelim_test.h" - - extern int nghttp2_enable_strict_preface; - -@@ -343,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_stream_reset_ratelim", -+ test_nghttp2_session_stream_reset_ratelim) || - !CU_add_test(pSuite, "http_mandatory_headers", - test_nghttp2_http_mandatory_headers) || - !CU_add_test(pSuite, "http_content_length", -@@ -449,7 +452,9 @@ int main(void) { - !CU_add_test(pSuite, "bufs_realloc", test_nghttp2_bufs_realloc) || - !CU_add_test(pSuite, "http_parse_priority", - test_nghttp2_http_parse_priority) || -- !CU_add_test(pSuite, "extpri_to_uint8", test_nghttp2_extpri_to_uint8)) { -+ !CU_add_test(pSuite, "extpri_to_uint8", test_nghttp2_extpri_to_uint8) || -+ !CU_add_test(pSuite, "ratelim_update", test_nghttp2_ratelim_update) || -+ !CU_add_test(pSuite, "ratelim_drain", test_nghttp2_ratelim_drain)) { - CU_cleanup_registry(); - return (int)CU_get_error(); - } -diff --git a/tests/nghttp2_ratelim_test.c b/tests/nghttp2_ratelim_test.c -new file mode 100644 -index 00000000..6abece95 ---- /dev/null -+++ b/tests/nghttp2_ratelim_test.c -@@ -0,0 +1,101 @@ -+/* -+ * nghttp2 - HTTP/2 C Library -+ * -+ * Copyright (c) 2023 nghttp2 contributors -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sublicense, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#include "nghttp2_ratelim_test.h" -+ -+#include -+ -+#include -+ -+#include "nghttp2_ratelim.h" -+ -+void test_nghttp2_ratelim_update(void) { -+ nghttp2_ratelim rl; -+ -+ nghttp2_ratelim_init(&rl, 1000, 21); -+ -+ CU_ASSERT(1000 == rl.val); -+ CU_ASSERT(1000 == rl.burst); -+ CU_ASSERT(21 == rl.rate); -+ CU_ASSERT(0 == rl.tstamp); -+ -+ nghttp2_ratelim_update(&rl, 999); -+ -+ CU_ASSERT(1000 == rl.val); -+ CU_ASSERT(999 == rl.tstamp); -+ -+ nghttp2_ratelim_drain(&rl, 100); -+ -+ CU_ASSERT(900 == rl.val); -+ -+ nghttp2_ratelim_update(&rl, 1000); -+ -+ CU_ASSERT(921 == rl.val); -+ -+ nghttp2_ratelim_update(&rl, 1002); -+ -+ CU_ASSERT(963 == rl.val); -+ -+ nghttp2_ratelim_update(&rl, 1004); -+ -+ CU_ASSERT(1000 == rl.val); -+ CU_ASSERT(1004 == rl.tstamp); -+ -+ /* timer skew */ -+ nghttp2_ratelim_init(&rl, 1000, 21); -+ nghttp2_ratelim_update(&rl, 1); -+ -+ CU_ASSERT(1000 == rl.val); -+ -+ nghttp2_ratelim_update(&rl, 0); -+ -+ CU_ASSERT(1000 == rl.val); -+ -+ /* rate * duration overflow */ -+ nghttp2_ratelim_init(&rl, 1000, 100); -+ nghttp2_ratelim_drain(&rl, 999); -+ -+ CU_ASSERT(1 == rl.val); -+ -+ nghttp2_ratelim_update(&rl, UINT64_MAX); -+ -+ CU_ASSERT(1000 == rl.val); -+ -+ /* val + rate * duration overflow */ -+ nghttp2_ratelim_init(&rl, UINT64_MAX - 1, 2); -+ nghttp2_ratelim_update(&rl, 1); -+ -+ CU_ASSERT(UINT64_MAX - 1 == rl.val); -+} -+ -+void test_nghttp2_ratelim_drain(void) { -+ nghttp2_ratelim rl; -+ -+ nghttp2_ratelim_init(&rl, 100, 7); -+ -+ CU_ASSERT(-1 == nghttp2_ratelim_drain(&rl, 101)); -+ CU_ASSERT(0 == nghttp2_ratelim_drain(&rl, 51)); -+ CU_ASSERT(0 == nghttp2_ratelim_drain(&rl, 49)); -+ CU_ASSERT(-1 == nghttp2_ratelim_drain(&rl, 1)); -+} -diff --git a/tests/nghttp2_ratelim_test.h b/tests/nghttp2_ratelim_test.h -new file mode 100644 -index 00000000..02b2f2b2 ---- /dev/null -+++ b/tests/nghttp2_ratelim_test.h -@@ -0,0 +1,35 @@ -+/* -+ * nghttp2 - HTTP/2 C Library -+ * -+ * Copyright (c) 2023 nghttp2 contributors -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining -+ * a copy of this software and associated documentation files (the -+ * "Software"), to deal in the Software without restriction, including -+ * without limitation the rights to use, copy, modify, merge, publish, -+ * distribute, sublicense, and/or sell copies of the Software, and to -+ * permit persons to whom the Software is furnished to do so, subject to -+ * the following conditions: -+ * -+ * The above copyright notice and this permission notice shall be -+ * included in all copies or substantial portions of the Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -+ */ -+#ifndef NGHTTP2_RATELIM_TEST_H -+#define NGHTTP2_RATELIM_TEST_H -+ -+#ifdef HAVE_CONFIG_H -+# include -+#endif /* HAVE_CONFIG_H */ -+ -+void test_nghttp2_ratelim_update(void); -+void test_nghttp2_ratelim_drain(void); -+ -+#endif /* NGHTTP2_RATELIM_TEST_H */ -diff --git a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c -index 74352426..e9941156 100644 ---- a/tests/nghttp2_session_test.c -+++ b/tests/nghttp2_session_test.c -@@ -11978,6 +11978,109 @@ void test_nghttp2_session_server_fallback_rfc7540_priorities(void) { - nghttp2_bufs_free(&bufs); - } - -+void test_nghttp2_session_stream_reset_ratelim(void) { -+ nghttp2_session *session; -+ nghttp2_session_callbacks callbacks; -+ nghttp2_frame frame; -+ ssize_t rv; -+ nghttp2_bufs bufs; -+ nghttp2_buf *buf; -+ nghttp2_mem *mem; -+ size_t i; -+ nghttp2_hd_deflater deflater; -+ size_t nvlen; -+ nghttp2_nv *nva; -+ int32_t stream_id; -+ nghttp2_outbound_item *item; -+ nghttp2_option *option; -+ -+ mem = nghttp2_mem_default(); -+ frame_pack_bufs_init(&bufs); -+ -+ memset(&callbacks, 0, sizeof(nghttp2_session_callbacks)); -+ callbacks.send_callback = null_send_callback; -+ -+ nghttp2_option_new(&option); -+ nghttp2_option_set_stream_reset_rate_limit( -+ option, NGHTTP2_DEFAULT_STREAM_RESET_BURST, 0); -+ -+ nghttp2_session_server_new2(&session, &callbacks, NULL, option); -+ -+ nghttp2_frame_settings_init(&frame.settings, NGHTTP2_FLAG_NONE, NULL, 0); -+ rv = nghttp2_frame_pack_settings(&bufs, &frame.settings); -+ -+ CU_ASSERT(0 == rv); -+ -+ nghttp2_frame_settings_free(&frame.settings, mem); -+ -+ buf = &bufs.head->buf; -+ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf)); -+ -+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv); -+ -+ /* Send SETTINGS ACK */ -+ rv = nghttp2_session_send(session); -+ -+ CU_ASSERT(0 == rv); -+ -+ nghttp2_hd_deflate_init(&deflater, mem); -+ -+ for (i = 0; i < NGHTTP2_DEFAULT_STREAM_RESET_BURST + 2; ++i) { -+ stream_id = (int32_t)(i * 2 + 1); -+ -+ nghttp2_bufs_reset(&bufs); -+ -+ /* HEADERS */ -+ nvlen = ARRLEN(reqnv); -+ nghttp2_nv_array_copy(&nva, reqnv, nvlen, mem); -+ nghttp2_frame_headers_init(&frame.headers, NGHTTP2_FLAG_END_HEADERS, -+ stream_id, NGHTTP2_HCAT_HEADERS, NULL, nva, -+ nvlen); -+ 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_buf_len(buf)); -+ -+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv); -+ -+ nghttp2_bufs_reset(&bufs); -+ -+ /* RST_STREAM */ -+ nghttp2_frame_rst_stream_init(&frame.rst_stream, stream_id, -+ NGHTTP2_NO_ERROR); -+ nghttp2_frame_pack_rst_stream(&bufs, &frame.rst_stream); -+ nghttp2_frame_rst_stream_free(&frame.rst_stream); -+ -+ buf = &bufs.head->buf; -+ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf)); -+ -+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv); -+ -+ if (i < NGHTTP2_DEFAULT_STREAM_RESET_BURST) { -+ CU_ASSERT(0 == nghttp2_outbound_queue_size(&session->ob_reg)); -+ -+ continue; -+ } -+ -+ CU_ASSERT(1 == nghttp2_outbound_queue_size(&session->ob_reg)); -+ -+ item = nghttp2_session_get_next_ob_item(session); -+ -+ CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type); -+ CU_ASSERT(NGHTTP2_DEFAULT_STREAM_RESET_BURST * 2 + 1 == -+ item->frame.goaway.last_stream_id); -+ } -+ -+ nghttp2_hd_deflate_free(&deflater); -+ nghttp2_session_del(session); -+ 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) { -diff --git a/tests/nghttp2_session_test.h b/tests/nghttp2_session_test.h -index e776813f..be4fdf89 100644 ---- a/tests/nghttp2_session_test.h -+++ b/tests/nghttp2_session_test.h -@@ -168,6 +168,7 @@ void test_nghttp2_session_no_closed_streams(void); - 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_stream_reset_ratelim(void); - void test_nghttp2_http_mandatory_headers(void); - void test_nghttp2_http_content_length(void); - void test_nghttp2_http_content_length_mismatch(void); --- -2.41.0 diff --git a/backport-Fix-build-error-when-both-clock_gettime-and-GetTickCount64.patch b/backport-Fix-build-error-when-both-clock_gettime-and-GetTickCount64.patch deleted file mode 100644 index 41d8223fbb1ec9805a8f7c189376d45aaf5f19a6..0000000000000000000000000000000000000000 --- a/backport-Fix-build-error-when-both-clock_gettime-and-GetTickCount64.patch +++ /dev/null @@ -1,39 +0,0 @@ -From bf8f419ca9f2d8bce48591710aa25f08e3fc67f8 Mon Sep 17 00:00:00 2001 -From: Tatsuhiro Tsujikawa -Date: Wed, 11 Oct 2023 17:19:05 +0900 -Subject: [PATCH] Fix build error when both clock_gettime and GetTickCount64 are available - -Conflict:NA -Reference:https://github.com/nghttp2/nghttp2/commit/bf8f419ca9f2d8bce48591710aa25f08e3fc67f8 - ---- - lib/nghttp2_time.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/lib/nghttp2_time.c b/lib/nghttp2_time.c -index 2a5f1a6..dd5a655 100644 ---- a/lib/nghttp2_time.c -+++ b/lib/nghttp2_time.c -@@ -44,7 +44,9 @@ static uint64_t time_now_sec(void) { - } - #endif /* HAVE_GETTICKCOUNT64 */ - --#ifdef HAVE_CLOCK_GETTIME -+#ifdef HAVE_GETTICKCOUNT64 -+uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; } -+#elif defined(HAVE_CLOCK_GETTIME) - uint64_t nghttp2_time_now_sec(void) { - struct timespec tp; - int rv = clock_gettime(CLOCK_MONOTONIC, &tp); -@@ -55,8 +57,6 @@ uint64_t nghttp2_time_now_sec(void) { - - return (uint64_t)tp.tv_sec; - } --#elif defined(HAVE_GETTICKCOUNT64) --uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; } - #else /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */ - uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); } - #endif /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */ --- -2.33.0 - diff --git a/nghttp2-1.55.1.tar.xz b/nghttp2-1.55.1.tar.xz deleted file mode 100644 index af283240368836f1041ad1e98aa47b220099ceba..0000000000000000000000000000000000000000 Binary files a/nghttp2-1.55.1.tar.xz and /dev/null differ diff --git a/nghttp2-1.58.0.tar.xz b/nghttp2-1.58.0.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..e7baf38c6f5f396a91e599538c0adb6015f47090 Binary files /dev/null and b/nghttp2-1.58.0.tar.xz differ diff --git a/nghttp2.spec b/nghttp2.spec index e077374b48d97680e27cd4333c4d84bf1e11565b..90c2ca4eeacdc3bd9c3850c43ff469a1206a50cc 100644 --- a/nghttp2.spec +++ b/nghttp2.spec @@ -1,14 +1,11 @@ Name: nghttp2 -Version: 1.55.1 -Release: 2 +Version: 1.58.0 +Release: 1 Summary: Contains the HTTP/2 client, server and proxy programs. License: MIT URL: https://nghttp2.org/ Source0: https://github.com/nghttp2/nghttp2/releases/download/v%{version}/%{name}-%{version}.tar.xz -Patch0: backport-CVE-2023-44487.patch -Patch1: backport-Fix-build-error-when-both-clock_gettime-and-GetTickCount64.patch - BuildRequires: CUnit-devel c-ares-devel gcc-c++ libev-devel openssl-devel automake BuildRequires: python3-devel systemd-devel zlib-devel make libxml2-devel @@ -92,6 +89,12 @@ export "LD_LIBRARY_PATH=$RPM_BUILD_ROOT%{_libdir}:$LD_LIBRARY_PATH" %{_mandir}/man1/* %changelog +* Wed Dec 27 2023 gaihuiying - 1.58.0-1 +- Type:requirements +- ID:NA +- SUG:NA +- DESC:update nghttp2 to 1.58.0 + * Thu Oct 19 2023 xingwei - 1.55.1-2 - Type:CVE - ID:CVE-2023-44487