From ad7542f44e3f2a6d2d8cf135766607cffaa0ea06 Mon Sep 17 00:00:00 2001 From: starlet-dx <15929766099@163.com> Date: Thu, 21 Oct 2021 14:27:37 +0800 Subject: [PATCH] fix CVE-2021-22930 --- CVE-2021-22930-1.patch | 71 ++++++++++++++++++++++++++++++++++++++++++ CVE-2021-22930-2.patch | 46 +++++++++++++++++++++++++++ CVE-2021-22930-3.patch | 53 +++++++++++++++++++++++++++++++ nodejs.spec | 8 ++++- 4 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 CVE-2021-22930-1.patch create mode 100644 CVE-2021-22930-2.patch create mode 100644 CVE-2021-22930-3.patch diff --git a/CVE-2021-22930-1.patch b/CVE-2021-22930-1.patch new file mode 100644 index 0000000..e08033c --- /dev/null +++ b/CVE-2021-22930-1.patch @@ -0,0 +1,71 @@ +From b263f2585ab53f56e0e22b46cf1f8519a8af8a05 Mon Sep 17 00:00:00 2001 +From: Akshay K +Date: Mon, 26 Jul 2021 08:21:51 -0400 +Subject: [PATCH] http2: on receiving rst_stream with cancel code add it to + pending list + +PR-URL: https://github.com/nodejs/node/pull/39423 +Backport-PR-URL: https://github.com/nodejs/node/pull/39527 +Fixes: https://github.com/nodejs/node/issues/38964 +Reviewed-By: James M Snell +Reviewed-By: Matteo Collina +--- + src/node_http2.cc | 17 +++++++++++++++++ + src/node_http2.h | 16 ++++++++++++++++ + 2 files changed, 33 insertions(+) + +diff --git a/src/node_http2.cc b/src/node_http2.cc +index dec6d7dab9ee..cc21373521e4 100644 +--- a/src/node_http2.cc ++++ b/src/node_http2.cc +@@ -2135,6 +2135,23 @@ int Http2Stream::SubmitPriority(nghttp2_priority_spec* prispec, + void Http2Stream::SubmitRstStream(const uint32_t code) { + CHECK(!this->IsDestroyed()); + code_ = code; ++ ++ // If RST_STREAM frame is received and stream is not writable ++ // because it is busy reading data, don't try force purging it. ++ // Instead add the stream to pending stream list and process ++ // the pending data when it is safe to do so. This is to avoid ++ // double free error due to unwanted behavior of nghttp2. ++ // Ref:https://github.com/nodejs/node/issues/38964 ++ ++ // Add stream to the pending list if it is received with scope ++ // below in the stack. The pending list may not get processed ++ // if RST_STREAM received is not in scope and added to the list ++ // causing endpoint to hang. ++ if (session_->is_in_scope() && IsReading()) { ++ session_->AddPendingRstStream(id_); ++ return; ++ } ++ + // If possible, force a purge of any currently pending data here to make sure + // it is sent before closing the stream. If it returns non-zero then we need + // to wait until the current write finishes and try again to avoid nghttp2 +diff --git a/src/node_http2.h b/src/node_http2.h +index 045bdfd716da..a59de18f920a 100644 +--- a/src/node_http2.h ++++ b/src/node_http2.h +@@ -764,6 +764,22 @@ class Http2Session : public AsyncWrap, + return (flags_ & SESSION_STATE_CLOSED) || session_ == nullptr; + } + ++ ++ // The changes are backported and exposes APIs to check the ++ // status flag of `Http2Session` ++#define IS_FLAG(name, flag) \ ++ bool is_##name() const { return flags_ & flag; } ++ ++ IS_FLAG(in_scope, SESSION_STATE_HAS_SCOPE) ++ IS_FLAG(write_scheduled, SESSION_STATE_WRITE_SCHEDULED) ++ IS_FLAG(closing, SESSION_STATE_CLOSING) ++ IS_FLAG(sending, SESSION_STATE_SENDING) ++ IS_FLAG(write_in_progress, SESSION_STATE_WRITE_IN_PROGRESS) ++ IS_FLAG(reading_stopped, SESSION_STATE_READING_STOPPED) ++ IS_FLAG(receive_paused, SESSION_STATE_NGHTTP2_RECV_PAUSED) ++ ++#undef IS_FLAG ++ + // Schedule a write if nghttp2 indicates it wants to write to the socket. + void MaybeScheduleWrite(); + diff --git a/CVE-2021-22930-2.patch b/CVE-2021-22930-2.patch new file mode 100644 index 0000000..68c3155 --- /dev/null +++ b/CVE-2021-22930-2.patch @@ -0,0 +1,46 @@ +From 1b61414ccdd0e1b5969219ba3ec7664d1f3ab495 Mon Sep 17 00:00:00 2001 +From: Akshay K +Date: Fri, 30 Jul 2021 18:46:45 -0400 +Subject: [PATCH] http2: update handling of rst_stream with error code + NGHTTP2_CANCEL + +--- + src/node_http2.cc | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/src/node_http2.cc b/src/node_http2.cc +index edbf531..6027318 100644 +--- a/src/node_http2.cc ++++ b/src/node_http2.cc +@@ -2136,18 +2136,19 @@ void Http2Stream::SubmitRstStream(const uint32_t code) { + CHECK(!this->IsDestroyed()); + code_ = code; + +- // If RST_STREAM frame is received and stream is not writable +- // because it is busy reading data, don't try force purging it. +- // Instead add the stream to pending stream list and process +- // the pending data when it is safe to do so. This is to avoid +- // double free error due to unwanted behavior of nghttp2. +- // Ref:https://github.com/nodejs/node/issues/38964 +- +- // Add stream to the pending list if it is received with scope ++ auto is_stream_cancel = [](const uint32_t code) { ++ return code == NGHTTP2_CANCEL; ++ }; ++ ++ // If RST_STREAM frame is received with error code NGHTTP2_CANCEL, ++ // add it to the pending list and don't force purge the data. It is ++ // to avoids the double free error due to unwanted behavior of nghttp2. ++ ++ // Add stream to the pending list only if it is received with scope + // below in the stack. The pending list may not get processed + // if RST_STREAM received is not in scope and added to the list + // causing endpoint to hang. +- if (session_->is_in_scope() && IsReading()) { ++ if (session_->is_in_scope() && is_stream_cancel(code)) { + session_->AddPendingRstStream(id_); + return; + } +-- +2.27.0 + diff --git a/CVE-2021-22930-3.patch b/CVE-2021-22930-3.patch new file mode 100644 index 0000000..ef9f70a --- /dev/null +++ b/CVE-2021-22930-3.patch @@ -0,0 +1,53 @@ +From 9b39a6b0c5e41a67c0fd180c884dca1b38e16b7b Mon Sep 17 00:00:00 2001 +From: Akshay K +Date: Thu, 5 Aug 2021 03:01:43 -0400 +Subject: [PATCH] http2: add tests for cancel event while client is paused + reading + +--- + .../test-http2-cancel-while-client-reading.js | 36 +++++++++++++++++++ + 1 file changed, 36 insertions(+) + create mode 100644 test/parallel/test-http2-cancel-while-client-reading.js + +diff --git a/test/parallel/test-http2-cancel-while-client-reading.js b/test/parallel/test-http2-cancel-while-client-reading.js +new file mode 100644 +index 000000000000..0605a02e1166 +--- /dev/null ++++ b/test/parallel/test-http2-cancel-while-client-reading.js +@@ -0,0 +1,36 @@ ++'use strict'; ++const common = require('../common'); ++const fixtures = require('../common/fixtures'); ++if (!common.hasCrypto) { ++ common.skip('missing crypto'); ++} ++ ++const http2 = require('http2'); ++const key = fixtures.readKey('agent1-key.pem', 'binary'); ++const cert = fixtures.readKey('agent1-cert.pem', 'binary'); ++ ++const server = http2.createSecureServer({ key, cert }); ++ ++let client_stream; ++ ++server.on('stream', common.mustCall(function(stream) { ++ stream.resume(); ++ stream.on('data', function(chunk) { ++ stream.write(chunk); ++ client_stream.pause(); ++ client_stream.close(http2.constants.NGHTTP2_CANCEL); ++ }); ++})); ++ ++server.listen(0, function() { ++ const client = http2.connect(`https://localhost:${server.address().port}`, ++ { rejectUnauthorized: false } ++ ); ++ client_stream = client.request({ ':method': 'POST' }); ++ client_stream.on('close', common.mustCall(() => { ++ client.close(); ++ server.close(); ++ })); ++ client_stream.resume(); ++ client_stream.write(Buffer.alloc(1024 * 1024)); ++}); diff --git a/nodejs.spec b/nodejs.spec index e846638..4b9c1dd 100644 --- a/nodejs.spec +++ b/nodejs.spec @@ -1,5 +1,5 @@ %bcond_with bootstrap -%global baserelease 6 +%global baserelease 7 %{?!_pkgdocdir:%global _pkgdocdir %{_docdir}/%{name}-%{version}} %global nodejs_epoch 1 %global nodejs_major 10 @@ -77,6 +77,9 @@ Patch5: CVE-2020-8265.patch Patch6: CVE-2020-8287.patch Patch7: CVE-2021-22883.patch Patch8: CVE-2021-22884.patch +Patch9: CVE-2021-22930-1.patch +Patch10: CVE-2021-22930-2.patch +Patch11: CVE-2021-22930-3.patch BuildRequires: python2-devel python3-devel zlib-devel gcc >= 6.3.0 BuildRequires: gcc-c++ >= 6.3.0 nodejs-packaging chrpath libatomic @@ -466,6 +469,9 @@ end %changelog +* Thu Oct 21 2021 yaoxin - 1:10.21.0-7 +- fix CVE-2021-22930 + * Mon Mar 15 2021 xinghe - 1:10.21.0-6 - fix CVE-2021-22883 CVE-2021-22884 -- Gitee