summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRahul Taya <Rahul.Taya@kpit.com>2021-02-25 13:02:59 +0530
committerArmin Kuster <akuster808@gmail.com>2021-03-16 08:40:06 -0700
commita8e3b20df3e1a97601bc54da9b2f1405c2056f7b (patch)
treede5142ff7be827982f4cd45e632212bb8aec5e2b
parent453bd7845fb4f9f67937b93bc7fd2275ca8f203b (diff)
downloadmeta-openembedded-a8e3b20df3e1a97601bc54da9b2f1405c2056f7b.tar.gz
nghttp2: Add fix for CVE-2020-11080
Added below two patches to fix CVE-2020-11080: 1. CVE-2020-11080-1.patch 2. CVE-2020-11080-2.patch Signed-off-by: Rahul Taya <Rahul.Taya@kpit.com> [Refreshed patches to apply] Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r--meta-networking/recipes-support/nghttp2/nghttp2/CVE-2020-11080-1.patch31
-rw-r--r--meta-networking/recipes-support/nghttp2/nghttp2/CVE-2020-11080-2.patch308
-rw-r--r--meta-networking/recipes-support/nghttp2/nghttp2_1.40.0.bb2
3 files changed, 341 insertions, 0 deletions
diff --git a/meta-networking/recipes-support/nghttp2/nghttp2/CVE-2020-11080-1.patch b/meta-networking/recipes-support/nghttp2/nghttp2/CVE-2020-11080-1.patch
new file mode 100644
index 000000000..ca181bb4b
--- /dev/null
+++ b/meta-networking/recipes-support/nghttp2/nghttp2/CVE-2020-11080-1.patch
@@ -0,0 +1,31 @@
1From f8da73bd042f810f34d19f9eae02b46d870af394 Mon Sep 17 00:00:00 2001
2From: James M Snell <jasnell@gmail.com>
3Date: Sun, 19 Apr 2020 09:12:24 -0700
4Subject: [PATCH] Earlier check for settings flood
5
6CVE: CVE-2020-11080
7Upstream-Status: Backport [https://github.com/nghttp2/nghttp2/commit/f8da73bd042f810f34d19f9eae02b46d870af394.patch]
8Comment: No hunk refreshed
9Affects-version: < v1.41.0
10Signed-off-by: Rahul Taya <Rahul.Taya@kpit.com>
11---
12 lib/nghttp2_session.c | 6 ++++++
13 1 file changed, 6 insertions(+)
14
15Index: nghttp2-1.40.0/lib/nghttp2_session.c
16===================================================================
17--- nghttp2-1.40.0.orig/lib/nghttp2_session.c
18+++ nghttp2-1.40.0/lib/nghttp2_session.c
19@@ -5678,6 +5678,12 @@ ssize_t nghttp2_session_mem_recv(nghttp2
20 break;
21 }
22
23+ /* Check the settings flood counter early to be safe */
24+ if (session->obq_flood_counter_ >= session->max_outbound_ack &&
25+ !(iframe->frame.hd.flags & NGHTTP2_FLAG_ACK)) {
26+ return NGHTTP2_ERR_FLOODED;
27+ }
28+
29 iframe->state = NGHTTP2_IB_READ_SETTINGS;
30
31 if (iframe->payloadleft) {
diff --git a/meta-networking/recipes-support/nghttp2/nghttp2/CVE-2020-11080-2.patch b/meta-networking/recipes-support/nghttp2/nghttp2/CVE-2020-11080-2.patch
new file mode 100644
index 000000000..d3c57e9a8
--- /dev/null
+++ b/meta-networking/recipes-support/nghttp2/nghttp2/CVE-2020-11080-2.patch
@@ -0,0 +1,308 @@
1From 336a98feb0d56b9ac54e12736b18785c27f75090 Mon Sep 17 00:00:00 2001
2From: James M Snell <jasnell@gmail.com>
3Date: Fri, 17 Apr 2020 16:53:51 -0700
4Subject: [PATCH] Implement max settings option
5
6CVE: CVE-2020-11080
7Upstream-Status: Backport [https://github.com/nghttp2/nghttp2/commit/336a98feb0d56b9ac54e12736b18785c27f75090.patch]
8Comment: No hunks refreshed
9Affects-version: < v1.41.0
10Signed-off-by: Rahul Taya <Rahul.Taya@kpit.com>
11---
12 doc/CMakeLists.txt | 1 +
13 doc/Makefile.am | 1 +
14 lib/includes/nghttp2/nghttp2.h | 23 +++++++++++++
15 lib/nghttp2_helper.c | 2 ++
16 lib/nghttp2_option.c | 5 +++
17 lib/nghttp2_option.h | 5 +++
18 lib/nghttp2_session.c | 21 ++++++++++++
19 lib/nghttp2_session.h | 2 ++
20 tests/main.c | 2 ++
21 tests/nghttp2_session_test.c | 61 ++++++++++++++++++++++++++++++++++
22 tests/nghttp2_session_test.h | 1 +
23 11 files changed, 124 insertions(+)
24
25Index: nghttp2-1.40.0/doc/CMakeLists.txt
26===================================================================
27--- nghttp2-1.40.0.orig/doc/CMakeLists.txt
28+++ nghttp2-1.40.0/doc/CMakeLists.txt
29@@ -42,6 +42,7 @@ set(APIDOCS
30 nghttp2_option_set_no_recv_client_magic.rst
31 nghttp2_option_set_peer_max_concurrent_streams.rst
32 nghttp2_option_set_user_recv_extension_type.rst
33+ nghttp2_option_set_max_settings.rst
34 nghttp2_pack_settings_payload.rst
35 nghttp2_priority_spec_check_default.rst
36 nghttp2_priority_spec_default_init.rst
37Index: nghttp2-1.40.0/lib/includes/nghttp2/nghttp2.h
38===================================================================
39--- nghttp2-1.40.0.orig/lib/includes/nghttp2/nghttp2.h
40+++ nghttp2-1.40.0/lib/includes/nghttp2/nghttp2.h
41@@ -229,6 +229,13 @@ typedef struct {
42 #define NGHTTP2_CLIENT_MAGIC_LEN 24
43
44 /**
45+ * @macro
46+ *
47+ * The default max number of settings per SETTINGS frame
48+ */
49+#define NGHTTP2_DEFAULT_MAX_SETTINGS 32
50+
51+/**
52 * @enum
53 *
54 * Error codes used in this library. The code range is [-999, -500],
55@@ -399,6 +406,11 @@ typedef enum {
56 */
57 NGHTTP2_ERR_SETTINGS_EXPECTED = -536,
58 /**
59+ * When a local endpoint receives too many settings entries
60+ * in a single SETTINGS frame.
61+ */
62+ NGHTTP2_ERR_TOO_MANY_SETTINGS = -537,
63+ /**
64 * The errors < :enum:`NGHTTP2_ERR_FATAL` mean that the library is
65 * under unexpected condition and processing was terminated (e.g.,
66 * out of memory). If application receives this error code, it must
67@@ -2661,6 +2673,17 @@ NGHTTP2_EXTERN void nghttp2_option_set_m
68
69 /**
70 * @function
71+ *
72+ * This function sets the maximum number of SETTINGS entries per
73+ * SETTINGS frame that will be accepted. If more than those entries
74+ * are received, the peer is considered to be misbehaving and session
75+ * will be closed. The default value is 32.
76+ */
77+NGHTTP2_EXTERN void nghttp2_option_set_max_settings(nghttp2_option *option,
78+ size_t val);
79+
80+/**
81+ * @function
82 *
83 * Initializes |*session_ptr| for client use. The all members of
84 * |callbacks| are copied to |*session_ptr|. Therefore |*session_ptr|
85Index: nghttp2-1.40.0/lib/nghttp2_helper.c
86===================================================================
87--- nghttp2-1.40.0.orig/lib/nghttp2_helper.c
88+++ nghttp2-1.40.0/lib/nghttp2_helper.c
89@@ -334,6 +334,8 @@ const char *nghttp2_strerror(int error_c
90 case NGHTTP2_ERR_FLOODED:
91 return "Flooding was detected in this HTTP/2 session, and it must be "
92 "closed";
93+ case NGHTTP2_ERR_TOO_MANY_SETTINGS:
94+ return "SETTINGS frame contained more than the maximum allowed entries";
95 default:
96 return "Unknown error code";
97 }
98Index: nghttp2-1.40.0/lib/nghttp2_option.c
99===================================================================
100--- nghttp2-1.40.0.orig/lib/nghttp2_option.c
101+++ nghttp2-1.40.0/lib/nghttp2_option.c
102@@ -121,3 +121,8 @@ void nghttp2_option_set_max_outbound_ack
103 option->opt_set_mask |= NGHTTP2_OPT_MAX_OUTBOUND_ACK;
104 option->max_outbound_ack = val;
105 }
106+
107+void nghttp2_option_set_max_settings(nghttp2_option *option, size_t val) {
108+ option->opt_set_mask |= NGHTTP2_OPT_MAX_SETTINGS;
109+ option->max_settings = val;
110+}
111Index: nghttp2-1.40.0/lib/nghttp2_option.h
112===================================================================
113--- nghttp2-1.40.0.orig/lib/nghttp2_option.h
114+++ nghttp2-1.40.0/lib/nghttp2_option.h
115@@ -67,6 +67,7 @@ typedef enum {
116 NGHTTP2_OPT_MAX_DEFLATE_DYNAMIC_TABLE_SIZE = 1 << 9,
117 NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10,
118 NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11,
119+ NGHTTP2_OPT_MAX_SETTINGS = 1 << 12,
120 } nghttp2_option_flag;
121
122 /**
123@@ -86,6 +87,10 @@ struct nghttp2_option {
124 */
125 size_t max_outbound_ack;
126 /**
127+ * NGHTTP2_OPT_MAX_SETTINGS
128+ */
129+ size_t max_settings;
130+ /**
131 * Bitwise OR of nghttp2_option_flag to determine that which fields
132 * are specified.
133 */
134Index: nghttp2-1.40.0/lib/nghttp2_session.c
135===================================================================
136--- nghttp2-1.40.0.orig/lib/nghttp2_session.c
137+++ nghttp2-1.40.0/lib/nghttp2_session.c
138@@ -458,6 +458,7 @@ static int session_new(nghttp2_session *
139
140 (*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN;
141 (*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM;
142+ (*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS;
143
144 if (option) {
145 if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) &&
146@@ -521,6 +522,11 @@ static int session_new(nghttp2_session *
147 if (option->opt_set_mask & NGHTTP2_OPT_MAX_OUTBOUND_ACK) {
148 (*session_ptr)->max_outbound_ack = option->max_outbound_ack;
149 }
150+
151+ if ((option->opt_set_mask & NGHTTP2_OPT_MAX_SETTINGS) &&
152+ option->max_settings) {
153+ (*session_ptr)->max_settings = option->max_settings;
154+ }
155 }
156
157 rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
158@@ -5694,6 +5700,16 @@ ssize_t nghttp2_session_mem_recv(nghttp2
159 iframe->max_niv =
160 iframe->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1;
161
162+ if (iframe->max_niv - 1 > session->max_settings) {
163+ rv = nghttp2_session_terminate_session_with_reason(
164+ session, NGHTTP2_ENHANCE_YOUR_CALM,
165+ "SETTINGS: too many setting entries");
166+ if (nghttp2_is_fatal(rv)) {
167+ return rv;
168+ }
169+ return (ssize_t)inlen;
170+ }
171+
172 iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) *
173 iframe->max_niv);
174
175@@ -7460,6 +7476,11 @@ static int nghttp2_session_upgrade_inter
176 if (settings_payloadlen % NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH) {
177 return NGHTTP2_ERR_INVALID_ARGUMENT;
178 }
179+ /* SETTINGS frame contains too many settings */
180+ if (settings_payloadlen / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH
181+ > session->max_settings) {
182+ return NGHTTP2_ERR_TOO_MANY_SETTINGS;
183+ }
184 rv = nghttp2_frame_unpack_settings_payload2(&iv, &niv, settings_payload,
185 settings_payloadlen, mem);
186 if (rv != 0) {
187Index: nghttp2-1.40.0/lib/nghttp2_session.h
188===================================================================
189--- nghttp2-1.40.0.orig/lib/nghttp2_session.h
190+++ nghttp2-1.40.0/lib/nghttp2_session.h
191@@ -267,6 +267,8 @@ struct nghttp2_session {
192 /* The maximum length of header block to send. Calculated by the
193 same way as nghttp2_hd_deflate_bound() does. */
194 size_t max_send_header_block_length;
195+ /* The maximum number of settings accepted per SETTINGS frame. */
196+ size_t max_settings;
197 /* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
198 uint32_t next_stream_id;
199 /* The last stream ID this session initiated. For client session,
200Index: nghttp2-1.40.0/tests/main.c
201===================================================================
202--- nghttp2-1.40.0.orig/tests/main.c
203+++ nghttp2-1.40.0/tests/main.c
204@@ -315,6 +315,8 @@ int main() {
205 test_nghttp2_session_set_local_window_size) ||
206 !CU_add_test(pSuite, "session_cancel_from_before_frame_send",
207 test_nghttp2_session_cancel_from_before_frame_send) ||
208+ !CU_add_test(pSuite, "session_too_many_settings",
209+ test_nghttp2_session_too_many_settings) ||
210 !CU_add_test(pSuite, "session_removed_closed_stream",
211 test_nghttp2_session_removed_closed_stream) ||
212 !CU_add_test(pSuite, "session_pause_data",
213Index: nghttp2-1.40.0/tests/nghttp2_session_test.c
214===================================================================
215--- nghttp2-1.40.0.orig/tests/nghttp2_session_test.c
216+++ nghttp2-1.40.0/tests/nghttp2_session_test.c
217@@ -10558,6 +10558,67 @@ void test_nghttp2_session_cancel_from_be
218 nghttp2_session_del(session);
219 }
220
221+void test_nghttp2_session_too_many_settings(void) {
222+ nghttp2_session *session;
223+ nghttp2_option *option;
224+ nghttp2_session_callbacks callbacks;
225+ nghttp2_frame frame;
226+ nghttp2_bufs bufs;
227+ nghttp2_buf *buf;
228+ ssize_t rv;
229+ my_user_data ud;
230+ nghttp2_settings_entry iv[3];
231+ nghttp2_mem *mem;
232+ nghttp2_outbound_item *item;
233+
234+ mem = nghttp2_mem_default();
235+ frame_pack_bufs_init(&bufs);
236+
237+ memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
238+ callbacks.on_frame_recv_callback = on_frame_recv_callback;
239+ callbacks.send_callback = null_send_callback;
240+
241+ nghttp2_option_new(&option);
242+ nghttp2_option_set_max_settings(option, 1);
243+
244+ nghttp2_session_client_new2(&session, &callbacks, &ud, option);
245+
246+ CU_ASSERT(1 == session->max_settings);
247+
248+ nghttp2_option_del(option);
249+
250+ iv[0].settings_id = NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
251+ iv[0].value = 3000;
252+
253+ iv[1].settings_id = NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE;
254+ iv[1].value = 16384;
255+
256+ nghttp2_frame_settings_init(&frame.settings, NGHTTP2_FLAG_NONE, dup_iv(iv, 2),
257+ 2);
258+
259+ rv = nghttp2_frame_pack_settings(&bufs, &frame.settings);
260+
261+ CU_ASSERT(0 == rv);
262+ CU_ASSERT(nghttp2_bufs_len(&bufs) > 0);
263+
264+ nghttp2_frame_settings_free(&frame.settings, mem);
265+
266+ buf = &bufs.head->buf;
267+ assert(nghttp2_bufs_len(&bufs) == nghttp2_buf_len(buf));
268+
269+ ud.frame_recv_cb_called = 0;
270+
271+ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
272+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
273+
274+ item = nghttp2_session_get_next_ob_item(session);
275+ CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type);
276+
277+ nghttp2_bufs_reset(&bufs);
278+ nghttp2_bufs_free(&bufs);
279+ nghttp2_session_del(session);
280+}
281+
282 static void
283 prepare_session_removed_closed_stream(nghttp2_session *session,
284 nghttp2_hd_deflater *deflater) {
285Index: nghttp2-1.40.0/tests/nghttp2_session_test.h
286===================================================================
287--- nghttp2-1.40.0.orig/tests/nghttp2_session_test.h
288+++ nghttp2-1.40.0/tests/nghttp2_session_test.h
289@@ -156,6 +156,7 @@ void test_nghttp2_session_repeated_prior
290 void test_nghttp2_session_repeated_priority_submission(void);
291 void test_nghttp2_session_set_local_window_size(void);
292 void test_nghttp2_session_cancel_from_before_frame_send(void);
293+void test_nghttp2_session_too_many_settings(void);
294 void test_nghttp2_session_removed_closed_stream(void);
295 void test_nghttp2_session_pause_data(void);
296 void test_nghttp2_session_no_closed_streams(void);
297Index: nghttp2-1.40.0/doc/Makefile.am
298===================================================================
299--- nghttp2-1.40.0.orig/doc/Makefile.am
300+++ nghttp2-1.40.0/doc/Makefile.am
301@@ -69,6 +69,7 @@ APIDOCS= \
302 nghttp2_option_set_peer_max_concurrent_streams.rst \
303 nghttp2_option_set_user_recv_extension_type.rst \
304 nghttp2_option_set_max_outbound_ack.rst \
305+ nghttp2_option_set_max_settings.rst \
306 nghttp2_pack_settings_payload.rst \
307 nghttp2_priority_spec_check_default.rst \
308 nghttp2_priority_spec_default_init.rst \
diff --git a/meta-networking/recipes-support/nghttp2/nghttp2_1.40.0.bb b/meta-networking/recipes-support/nghttp2/nghttp2_1.40.0.bb
index 9ed8c5642..b497058ca 100644
--- a/meta-networking/recipes-support/nghttp2/nghttp2_1.40.0.bb
+++ b/meta-networking/recipes-support/nghttp2/nghttp2_1.40.0.bb
@@ -10,6 +10,8 @@ UPSTREAM_CHECK_URI = "https://github.com/nghttp2/nghttp2/releases"
10SRC_URI = "\ 10SRC_URI = "\
11 https://github.com/nghttp2/nghttp2/releases/download/v${PV}/nghttp2-${PV}.tar.xz \ 11 https://github.com/nghttp2/nghttp2/releases/download/v${PV}/nghttp2-${PV}.tar.xz \
12 file://0001-fetch-ocsp-response-use-python3.patch \ 12 file://0001-fetch-ocsp-response-use-python3.patch \
13 file://CVE-2020-11080-1.patch \
14 file://CVE-2020-11080-2.patch \
13" 15"
14SRC_URI[md5sum] = "8d1a6b96760254e4dd142d7176e8fb7c" 16SRC_URI[md5sum] = "8d1a6b96760254e4dd142d7176e8fb7c"
15SRC_URI[sha256sum] = "09fc43d428ff237138733c737b29fb1a7e49d49de06d2edbed3bc4cdcee69073" 17SRC_URI[sha256sum] = "09fc43d428ff237138733c737b29fb1a7e49d49de06d2edbed3bc4cdcee69073"