!74 [sync] PR-69: fix CVE-2021-22930

From: @openeuler-sync-bot
Reviewed-by: @solarhu
Signed-off-by: @solarhu
This commit is contained in:
openeuler-ci-bot 2021-10-25 02:52:48 +00:00 committed by Gitee
commit 18d74738a4
4 changed files with 177 additions and 1 deletions

71
CVE-2021-22930-1.patch Normal file
View File

@ -0,0 +1,71 @@
From b263f2585ab53f56e0e22b46cf1f8519a8af8a05 Mon Sep 17 00:00:00 2001
From: Akshay K <iit.akshay@gmail.com>
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 <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
---
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();

46
CVE-2021-22930-2.patch Normal file
View File

@ -0,0 +1,46 @@
From 1b61414ccdd0e1b5969219ba3ec7664d1f3ab495 Mon Sep 17 00:00:00 2001
From: Akshay K <iit.akshay@gmail.com>
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

53
CVE-2021-22930-3.patch Normal file
View File

@ -0,0 +1,53 @@
From 9b39a6b0c5e41a67c0fd180c884dca1b38e16b7b Mon Sep 17 00:00:00 2001
From: Akshay K <iit.akshay@gmail.com>
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));
+});

View File

@ -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 12
@ -92,6 +92,9 @@ Patch0008: CVE-2021-22883.patch
Patch0009: CVE-2021-22884.patch
Patch00010: CVE-2021-22918.patch
Patch00011: 0005-use-getauxval-in-node_main_cc.patch
Patch00012: CVE-2021-22930-1.patch
Patch00013: CVE-2021-22930-2.patch
Patch00014: CVE-2021-22930-3.patch
BuildRequires: python3-devel
BuildRequires: zlib-devel
@ -494,6 +497,9 @@ end
%{_pkgdocdir}/npm/docs
%changelog
* Thu Oct 21 2021 yaoxin <yaoxin30@huawei.com> - 1:12.18.4-7
- fix CVE-2021-22930
* Mon Aug 16 2021 zhouwenpei <zhouwenpei1@huawei.com> - 1:12.18.4-6
- use getauxval to fix build failure in node_main.cc