!81 Update to 12.22.11, fix some cves.
From: @wk333 Reviewed-by: @solarhu Signed-off-by: @solarhu
This commit is contained in:
commit
0ca2b75e6e
@ -1,25 +0,0 @@
|
||||
From 7fddd1453f365e54b46f6564d5c168ed13e758db Mon Sep 17 00:00:00 2001
|
||||
From: lingsheng <lingsheng@huawei.com>
|
||||
Date: Wed, 18 Nov 2020 14:58:37 +0800
|
||||
Subject: [PATCH] Modify openEuler aarch64 v8_os_page_size to 64
|
||||
|
||||
---
|
||||
deps/v8/src/flags/flag-definitions.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/deps/v8/src/flags/flag-definitions.h b/deps/v8/src/flags/flag-definitions.h
|
||||
index c7c07e6d..38a035e2 100644
|
||||
--- a/deps/v8/src/flags/flag-definitions.h
|
||||
+++ b/deps/v8/src/flags/flag-definitions.h
|
||||
@@ -917,7 +917,7 @@ DEFINE_BOOL(memory_reducer_for_small_heaps, true,
|
||||
"use memory reducer for small heaps")
|
||||
DEFINE_INT(heap_growing_percent, 0,
|
||||
"specifies heap growing factor as (1 + heap_growing_percent/100)")
|
||||
-DEFINE_INT(v8_os_page_size, 0, "override OS page size (in KBytes)")
|
||||
+DEFINE_INT(v8_os_page_size, 64, "override OS page size (in KBytes)")
|
||||
DEFINE_BOOL(always_compact, false, "Perform compaction on every full GC")
|
||||
DEFINE_BOOL(never_compact, false,
|
||||
"Never perform compaction on full GC - testing only")
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,164 +0,0 @@
|
||||
From 5b00de7d67a1372aa342115ad28edd3f78268bb6 Mon Sep 17 00:00:00 2001
|
||||
From: James M Snell <jasnell@gmail.com>
|
||||
Date: Thu, 12 Nov 2020 12:34:33 -0800
|
||||
Subject: [PATCH] src: retain pointers to WriteWrap/ShutdownWrap
|
||||
|
||||
Avoids potential use-after-free when wrap req's are synchronously
|
||||
destroyed.
|
||||
|
||||
CVE-ID: CVE-2020-8265
|
||||
Fixes: https://github.com/nodejs-private/node-private/issues/227
|
||||
PR-URL: https://github.com/nodejs-private/node-private/pull/230
|
||||
Refs: https://hackerone.com/bugs?subject=nodejs&report_id=988103
|
||||
Reviewed-By: Anna Henningsen <anna@addaleax.net>
|
||||
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
||||
Reviewed-By: Rich Trott <rtrott@gmail.com>
|
||||
Reference: https://github.com/nodejs/node/commit/5b00de7d67a1372aa342115ad28edd3f78268bb6
|
||||
---
|
||||
src/stream_base-inl.h | 11 +++-
|
||||
src/stream_base.cc | 2 +-
|
||||
src/stream_base.h | 1 +
|
||||
.../test-tls-use-after-free-regression.js | 58 +++++++++++++++++++
|
||||
4 files changed, 68 insertions(+), 4 deletions(-)
|
||||
create mode 100644 test/parallel/test-tls-use-after-free-regression.js
|
||||
|
||||
diff --git a/src/stream_base-inl.h b/src/stream_base-inl.h
|
||||
index dd80683af10..1603a2fb2e0 100644
|
||||
--- a/src/stream_base-inl.h
|
||||
+++ b/src/stream_base-inl.h
|
||||
@@ -163,8 +163,11 @@ inline int StreamBase::Shutdown(v8::Local<v8::Object> req_wrap_obj) {
|
||||
StreamReq::ResetObject(req_wrap_obj);
|
||||
}
|
||||
|
||||
+ BaseObjectPtr<AsyncWrap> req_wrap_ptr;
|
||||
AsyncHooks::DefaultTriggerAsyncIdScope trigger_scope(GetAsyncWrap());
|
||||
ShutdownWrap* req_wrap = CreateShutdownWrap(req_wrap_obj);
|
||||
+ if (req_wrap != nullptr)
|
||||
+ req_wrap_ptr.reset(req_wrap->GetAsyncWrap());
|
||||
int err = DoShutdown(req_wrap);
|
||||
|
||||
if (err != 0 && req_wrap != nullptr) {
|
||||
@@ -198,7 +201,7 @@ inline StreamWriteResult StreamBase::Write(
|
||||
if (send_handle == nullptr) {
|
||||
err = DoTryWrite(&bufs, &count);
|
||||
if (err != 0 || count == 0) {
|
||||
- return StreamWriteResult { false, err, nullptr, total_bytes };
|
||||
+ return StreamWriteResult { false, err, nullptr, total_bytes, {} };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,13 +211,14 @@ inline StreamWriteResult StreamBase::Write(
|
||||
if (!env->write_wrap_template()
|
||||
->NewInstance(env->context())
|
||||
.ToLocal(&req_wrap_obj)) {
|
||||
- return StreamWriteResult { false, UV_EBUSY, nullptr, 0 };
|
||||
+ return StreamWriteResult { false, UV_EBUSY, nullptr, 0, {} };
|
||||
}
|
||||
StreamReq::ResetObject(req_wrap_obj);
|
||||
}
|
||||
|
||||
AsyncHooks::DefaultTriggerAsyncIdScope trigger_scope(GetAsyncWrap());
|
||||
WriteWrap* req_wrap = CreateWriteWrap(req_wrap_obj);
|
||||
+ BaseObjectPtr<AsyncWrap> req_wrap_ptr(req_wrap->GetAsyncWrap());
|
||||
|
||||
err = DoWrite(req_wrap, bufs, count, send_handle);
|
||||
bool async = err == 0;
|
||||
@@ -232,7 +236,8 @@ inline StreamWriteResult StreamBase::Write(
|
||||
ClearError();
|
||||
}
|
||||
|
||||
- return StreamWriteResult { async, err, req_wrap, total_bytes };
|
||||
+ return StreamWriteResult {
|
||||
+ async, err, req_wrap, total_bytes, std::move(req_wrap_ptr) };
|
||||
}
|
||||
|
||||
template <typename OtherBase>
|
||||
diff --git a/src/stream_base.cc b/src/stream_base.cc
|
||||
index 516f57e40bf..06032e2c096 100644
|
||||
--- a/src/stream_base.cc
|
||||
+++ b/src/stream_base.cc
|
||||
@@ -259,7 +259,7 @@ int StreamBase::WriteString(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
// Immediate failure or success
|
||||
if (err != 0 || count == 0) {
|
||||
- SetWriteResult(StreamWriteResult { false, err, nullptr, data_size });
|
||||
+ SetWriteResult(StreamWriteResult { false, err, nullptr, data_size, {} });
|
||||
return err;
|
||||
}
|
||||
|
||||
diff --git a/src/stream_base.h b/src/stream_base.h
|
||||
index eb75fdc8339..fafd327d75d 100644
|
||||
--- a/src/stream_base.h
|
||||
+++ b/src/stream_base.h
|
||||
@@ -24,6 +24,7 @@ struct StreamWriteResult {
|
||||
int err;
|
||||
WriteWrap* wrap;
|
||||
size_t bytes;
|
||||
+ BaseObjectPtr<AsyncWrap> wrap_obj;
|
||||
};
|
||||
|
||||
using JSMethodFunction = void(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
diff --git a/test/parallel/test-tls-use-after-free-regression.js b/test/parallel/test-tls-use-after-free-regression.js
|
||||
new file mode 100644
|
||||
index 00000000000..51835fc0339
|
||||
--- /dev/null
|
||||
+++ b/test/parallel/test-tls-use-after-free-regression.js
|
||||
@@ -0,0 +1,58 @@
|
||||
+'use strict';
|
||||
+
|
||||
+const common = require('../common');
|
||||
+
|
||||
+if (!common.hasCrypto)
|
||||
+ common.skip('missing crypto');
|
||||
+
|
||||
+const https = require('https');
|
||||
+const tls = require('tls');
|
||||
+
|
||||
+const kMessage =
|
||||
+ 'GET / HTTP/1.1\r\nHost: localhost\r\nConnection: Keep-alive\r\n\r\n';
|
||||
+
|
||||
+const key = `-----BEGIN EC PARAMETERS-----
|
||||
+BggqhkjOPQMBBw==
|
||||
+-----END EC PARAMETERS-----
|
||||
+-----BEGIN EC PRIVATE KEY-----
|
||||
+MHcCAQEEIDKfHHbiJMdu2STyHL11fWC7psMY19/gUNpsUpkwgGACoAoGCCqGSM49
|
||||
+AwEHoUQDQgAEItqm+pYj3Ca8bi5mBs+H8xSMxuW2JNn4I+kw3aREsetLk8pn3o81
|
||||
+PWBiTdSZrGBGQSy+UAlQvYeE6Z/QXQk8aw==
|
||||
+-----END EC PRIVATE KEY-----`;
|
||||
+
|
||||
+const cert = `-----BEGIN CERTIFICATE-----
|
||||
+MIIBhjCCASsCFDJU1tCo88NYU//pE+DQKO9hUDsFMAoGCCqGSM49BAMCMEUxCzAJ
|
||||
+BgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5l
|
||||
+dCBXaWRnaXRzIFB0eSBMdGQwHhcNMjAwOTIyMDg1NDU5WhcNNDgwMjA3MDg1NDU5
|
||||
+WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwY
|
||||
+SW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
|
||||
+QgAEItqm+pYj3Ca8bi5mBs+H8xSMxuW2JNn4I+kw3aREsetLk8pn3o81PWBiTdSZ
|
||||
+rGBGQSy+UAlQvYeE6Z/QXQk8azAKBggqhkjOPQQDAgNJADBGAiEA7Bdn4F87KqIe
|
||||
+Y/ABy/XIXXpFUb2nyv3zV7POQi2lPcECIQC3UWLmfiedpiIKsf9YRIyO0uEood7+
|
||||
+glj2R1NNr1X68w==
|
||||
+-----END CERTIFICATE-----`;
|
||||
+
|
||||
+const server = https.createServer(
|
||||
+ { key, cert },
|
||||
+ common.mustCall((req, res) => {
|
||||
+ res.writeHead(200);
|
||||
+ res.end('boom goes the dynamite\n');
|
||||
+ }, 3));
|
||||
+
|
||||
+server.listen(0, common.mustCall(() => {
|
||||
+ const socket =
|
||||
+ tls.connect(
|
||||
+ server.address().port,
|
||||
+ 'localhost',
|
||||
+ { rejectUnauthorized: false },
|
||||
+ common.mustCall(() => {
|
||||
+ socket.write(kMessage);
|
||||
+ socket.write(kMessage);
|
||||
+ socket.write(kMessage);
|
||||
+ }));
|
||||
+
|
||||
+ socket.on('data', common.mustCall(() => socket.destroy()));
|
||||
+ socket.on('close', () => {
|
||||
+ setImmediate(() => server.close());
|
||||
+ });
|
||||
+}));
|
||||
@ -1,79 +0,0 @@
|
||||
From 92d430917a63a567bb528100371263c46e50ee4a Mon Sep 17 00:00:00 2001
|
||||
From: Fedor Indutny <fedor@indutny.com>
|
||||
Date: Wed, 18 Nov 2020 20:50:21 -0800
|
||||
Subject: [PATCH] http: unset `F_CHUNKED` on new `Transfer-Encoding`
|
||||
|
||||
Duplicate `Transfer-Encoding` header should be a treated as a single,
|
||||
but with original header values concatenated with a comma separator. In
|
||||
the light of this, even if the past `Transfer-Encoding` ended with
|
||||
`chunked`, we should be not let the `F_CHUNKED` to leak into the next
|
||||
header, because mere presence of another header indicates that `chunked`
|
||||
is not the last transfer-encoding token.
|
||||
|
||||
CVE-ID: CVE-2020-8287
|
||||
PR-URL: https://github.com/nodejs-private/node-private/pull/236
|
||||
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
|
||||
Reference: https://github.com/nodejs/node/commit/92d430917a63a567bb528100371263c46e50ee4a
|
||||
---
|
||||
deps/http_parser/http_parser.c | 7 +++++++
|
||||
deps/http_parser/test.c | 26 ++++++++++++++++++++++++++
|
||||
2 files changed, 33 insertions(+)
|
||||
|
||||
diff --git a/deps/http_parser/http_parser.c b/deps/http_parser/http_parser.c
|
||||
index 0f76b6a..5cc951a 100644
|
||||
--- a/deps/http_parser/http_parser.c
|
||||
+++ b/deps/http_parser/http_parser.c
|
||||
@@ -1339,6 +1339,13 @@ reexecute:
|
||||
} else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
|
||||
parser->header_state = h_transfer_encoding;
|
||||
parser->flags |= F_TRANSFER_ENCODING;
|
||||
+
|
||||
+ /* Multiple `Transfer-Encoding` headers should be treated as
|
||||
+ * one, but with values separate by a comma.
|
||||
+ *
|
||||
+ * See: https://tools.ietf.org/html/rfc7230#section-3.2.2
|
||||
+ */
|
||||
+ parser->flags &= ~F_CHUNKED;
|
||||
}
|
||||
break;
|
||||
|
||||
diff --git a/deps/http_parser/test.c b/deps/http_parser/test.c
|
||||
index c979467..f185c56 100644
|
||||
--- a/deps/http_parser/test.c
|
||||
+++ b/deps/http_parser/test.c
|
||||
@@ -2045,6 +2045,32 @@ const struct message responses[] =
|
||||
,.body= "2\r\nOK\r\n0\r\n\r\n"
|
||||
,.num_chunks_complete= 0
|
||||
}
|
||||
+#define HTTP_200_DUPLICATE_TE_NOT_LAST_CHUNKED 30
|
||||
+, {.name= "HTTP 200 response with `chunked` and duplicate Transfer-Encoding"
|
||||
+ ,.type= HTTP_RESPONSE
|
||||
+ ,.raw= "HTTP/1.1 200 OK\r\n"
|
||||
+ "Transfer-Encoding: chunked\r\n"
|
||||
+ "Transfer-Encoding: identity\r\n"
|
||||
+ "\r\n"
|
||||
+ "2\r\n"
|
||||
+ "OK\r\n"
|
||||
+ "0\r\n"
|
||||
+ "\r\n"
|
||||
+ ,.should_keep_alive= FALSE
|
||||
+ ,.message_complete_on_eof= TRUE
|
||||
+ ,.http_major= 1
|
||||
+ ,.http_minor= 1
|
||||
+ ,.status_code= 200
|
||||
+ ,.response_status= "OK"
|
||||
+ ,.content_length= -1
|
||||
+ ,.num_headers= 2
|
||||
+ ,.headers=
|
||||
+ { { "Transfer-Encoding", "chunked" }
|
||||
+ , { "Transfer-Encoding", "identity" }
|
||||
+ }
|
||||
+ ,.body= "2\r\nOK\r\n0\r\n\r\n"
|
||||
+ ,.num_chunks_complete= 0
|
||||
+ }
|
||||
};
|
||||
|
||||
/* strnlen() is a POSIX.2008 addition. Can't rely on it being available so
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,151 +0,0 @@
|
||||
From 420244e4d9ca6de2612e7f503f5c87e448fbc14b Mon Sep 17 00:00:00 2001
|
||||
From: Matteo Collina <hello@matteocollina.com>
|
||||
Date: Thu, 22 Oct 2020 14:10:51 +0200
|
||||
Subject: [PATCH] http: unset `F_CHUNKED` on new `Transfer-Encoding`
|
||||
|
||||
Duplicate `Transfer-Encoding` header should be a treated as a single,
|
||||
but with original header values concatenated with a comma separator. In
|
||||
the light of this, even if the past `Transfer-Encoding` ended with
|
||||
`chunked`, we should be not let the `F_CHUNKED` to leak into the next
|
||||
header, because mere presence of another header indicates that `chunked`
|
||||
is not the last transfer-encoding token.
|
||||
|
||||
Ref: https://github.com/nodejs-private/llhttp-private/pull/3
|
||||
See: https://hackerone.com/bugs?report_id=1002188&subject=nodejs
|
||||
|
||||
CVE-ID: CVE-2020-8287
|
||||
PR-URL: https://github.com/nodejs-private/node-private/pull/236
|
||||
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
|
||||
Reference: https://github.com/nodejs/node/commit/420244e4d9ca6de2612e7f503f5c87e448fbc14b
|
||||
---
|
||||
deps/llhttp/src/llhttp.c | 36 ++++++++++++++-
|
||||
.../test-http-transfer-encoding-smuggling.js | 46 +++++++++++++++++++
|
||||
2 files changed, 80 insertions(+), 2 deletions(-)
|
||||
create mode 100644 test/parallel/test-http-transfer-encoding-smuggling.js
|
||||
|
||||
diff --git a/deps/llhttp/src/llhttp.c b/deps/llhttp/src/llhttp.c
|
||||
index acc35479f88..3019c410963 100644
|
||||
--- a/deps/llhttp/src/llhttp.c
|
||||
+++ b/deps/llhttp/src/llhttp.c
|
||||
@@ -813,6 +813,14 @@ int llhttp__internal__c_or_flags_16(
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int llhttp__internal__c_and_flags(
|
||||
+ llhttp__internal_t* state,
|
||||
+ const unsigned char* p,
|
||||
+ const unsigned char* endp) {
|
||||
+ state->flags &= -9;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int llhttp__internal__c_update_header_state_7(
|
||||
llhttp__internal_t* state,
|
||||
const unsigned char* p,
|
||||
@@ -5974,10 +5982,18 @@ static llparse_state_t llhttp__internal__run(
|
||||
/* UNREACHABLE */;
|
||||
abort();
|
||||
}
|
||||
+ s_n_llhttp__internal__n_invoke_and_flags: {
|
||||
+ switch (llhttp__internal__c_and_flags(state, p, endp)) {
|
||||
+ default:
|
||||
+ goto s_n_llhttp__internal__n_header_value_te_chunked;
|
||||
+ }
|
||||
+ /* UNREACHABLE */;
|
||||
+ abort();
|
||||
+ }
|
||||
s_n_llhttp__internal__n_invoke_or_flags_16: {
|
||||
switch (llhttp__internal__c_or_flags_16(state, p, endp)) {
|
||||
default:
|
||||
- goto s_n_llhttp__internal__n_header_value_te_chunked;
|
||||
+ goto s_n_llhttp__internal__n_invoke_and_flags;
|
||||
}
|
||||
/* UNREACHABLE */;
|
||||
abort();
|
||||
@@ -7625,6 +7641,14 @@ int llhttp__internal__c_or_flags_16(
|
||||
return 0;
|
||||
}
|
||||
|
||||
+int llhttp__internal__c_and_flags(
|
||||
+ llhttp__internal_t* state,
|
||||
+ const unsigned char* p,
|
||||
+ const unsigned char* endp) {
|
||||
+ state->flags &= -9;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
int llhttp__internal__c_update_header_state_7(
|
||||
llhttp__internal_t* state,
|
||||
const unsigned char* p,
|
||||
@@ -12522,10 +12546,18 @@ static llparse_state_t llhttp__internal__run(
|
||||
/* UNREACHABLE */;
|
||||
abort();
|
||||
}
|
||||
+ s_n_llhttp__internal__n_invoke_and_flags: {
|
||||
+ switch (llhttp__internal__c_and_flags(state, p, endp)) {
|
||||
+ default:
|
||||
+ goto s_n_llhttp__internal__n_header_value_te_chunked;
|
||||
+ }
|
||||
+ /* UNREACHABLE */;
|
||||
+ abort();
|
||||
+ }
|
||||
s_n_llhttp__internal__n_invoke_or_flags_16: {
|
||||
switch (llhttp__internal__c_or_flags_16(state, p, endp)) {
|
||||
default:
|
||||
- goto s_n_llhttp__internal__n_header_value_te_chunked;
|
||||
+ goto s_n_llhttp__internal__n_invoke_and_flags;
|
||||
}
|
||||
/* UNREACHABLE */;
|
||||
abort();
|
||||
diff --git a/test/parallel/test-http-transfer-encoding-smuggling.js b/test/parallel/test-http-transfer-encoding-smuggling.js
|
||||
new file mode 100644
|
||||
index 00000000000..9d97db4c0a2
|
||||
--- /dev/null
|
||||
+++ b/test/parallel/test-http-transfer-encoding-smuggling.js
|
||||
@@ -0,0 +1,46 @@
|
||||
+'use strict';
|
||||
+
|
||||
+const common = require('../common');
|
||||
+
|
||||
+const assert = require('assert');
|
||||
+const http = require('http');
|
||||
+const net = require('net');
|
||||
+
|
||||
+const msg = [
|
||||
+ 'POST / HTTP/1.1',
|
||||
+ 'Host: 127.0.0.1',
|
||||
+ 'Transfer-Encoding: chunked',
|
||||
+ 'Transfer-Encoding: chunked-false',
|
||||
+ 'Connection: upgrade',
|
||||
+ '',
|
||||
+ '1',
|
||||
+ 'A',
|
||||
+ '0',
|
||||
+ '',
|
||||
+ 'GET /flag HTTP/1.1',
|
||||
+ 'Host: 127.0.0.1',
|
||||
+ '',
|
||||
+ '',
|
||||
+].join('\r\n');
|
||||
+
|
||||
+// Verify that the server is called only once even with a smuggled request.
|
||||
+
|
||||
+const server = http.createServer(common.mustCall((req, res) => {
|
||||
+ res.end();
|
||||
+}, 1));
|
||||
+
|
||||
+function send(next) {
|
||||
+ const client = net.connect(server.address().port, 'localhost');
|
||||
+ client.setEncoding('utf8');
|
||||
+ client.on('error', common.mustNotCall());
|
||||
+ client.on('end', next);
|
||||
+ client.write(msg);
|
||||
+ client.resume();
|
||||
+}
|
||||
+
|
||||
+server.listen(0, common.mustCall((err) => {
|
||||
+ assert.ifError(err);
|
||||
+ send(common.mustCall(() => {
|
||||
+ server.close();
|
||||
+ }));
|
||||
+}));
|
||||
@ -1,219 +0,0 @@
|
||||
From 922ada77132c1b0b69c9a146822d762b2f9b912b Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Bevenius <daniel.bevenius@gmail.com>
|
||||
Date: Fri, 22 Jan 2021 12:34:21 +0100
|
||||
Subject: [PATCH] http2: add unknownProtocol timeout
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This commit add a configuration options named unknownProtocolTimeout
|
||||
which can be specified to set a value for the timeout in milliseconds
|
||||
that a server should wait when an unknowProtocol is sent to it. When
|
||||
this happens a timer will be started and the if the socket has not been
|
||||
destroyed during that time the timer callback will destoy it.
|
||||
|
||||
Refs: https://hackerone.com/reports/1043360
|
||||
CVE-ID: CVE-2021-22883
|
||||
PR-URL: https://github.com/nodejs/node/pull/246
|
||||
Backport-PR-URL: https://github.com/nodejs/node/pull/250
|
||||
Reviewed-By: Beth Griggs <bgriggs@redhat.com>
|
||||
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
||||
Reviewed-By: Michael Dawson <midawson@redhat.com>
|
||||
Reviewed-By: Rich Trott <rtrott@gmail.com>
|
||||
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
|
||||
Reference: https://github.com/nodejs/node/commit/922ada77132c1b0b69c9a146822d762b2f9b912b
|
||||
---
|
||||
doc/api/http2.md | 25 +++++++++++++-
|
||||
lib/internal/http2/core.js | 31 ++++++++++++++---
|
||||
.../test-http2-server-unknown-protocol.js | 33 +++++++++++++++++++
|
||||
3 files changed, 84 insertions(+), 5 deletions(-)
|
||||
create mode 100644 test/parallel/test-http2-server-unknown-protocol.js
|
||||
|
||||
diff --git a/doc/api/http2.md b/doc/api/http2.md
|
||||
index 40a107f..d57a560 100644
|
||||
--- a/doc/api/http2.md
|
||||
+++ b/doc/api/http2.md
|
||||
@@ -1908,7 +1908,9 @@ added: v8.4.0
|
||||
The `'unknownProtocol'` event is emitted when a connecting client fails to
|
||||
negotiate an allowed protocol (i.e. HTTP/2 or HTTP/1.1). The event handler
|
||||
receives the socket for handling. If no listener is registered for this event,
|
||||
-the connection is terminated. See the [Compatibility API][].
|
||||
+the connection is terminated. A timeout may be specified using the
|
||||
+`'unknownProtocolTimeout'` option passed to [`http2.createSecureServer()`][].
|
||||
+See the [Compatibility API][].
|
||||
|
||||
#### `server.close([callback])`
|
||||
<!-- YAML
|
||||
@@ -1948,6 +1950,9 @@ error will be thrown.
|
||||
<!-- YAML
|
||||
added: v8.4.0
|
||||
changes:
|
||||
+ - version: REPLACEME
|
||||
+ pr-url: https://github.com/nodejs-private/node-private/pull/250
|
||||
+ description: Added `unknownProtocolTimeout` option with a default of 10000.
|
||||
- version:
|
||||
- v12.18.0
|
||||
pr-url: https://github.com/nodejs-private/node-private/pull/206
|
||||
@@ -2050,6 +2055,10 @@ changes:
|
||||
`Http2ServerResponse` class to use.
|
||||
Useful for extending the original `Http2ServerResponse`.
|
||||
**Default:** `Http2ServerResponse`.
|
||||
+ * `unknownProtocolTimeout` {number} Specifies a timeout in milliseconds that
|
||||
+ a server should wait when an [`'unknownProtocol'`][] is emitted. If the
|
||||
+ socket has not been destroyed by that time the server will destroy it.
|
||||
+ **Default:** `10000`.
|
||||
* ...: Any [`net.createServer()`][] option can be provided.
|
||||
* `onRequestHandler` {Function} See [Compatibility API][]
|
||||
* Returns: {Http2Server}
|
||||
@@ -2086,6 +2095,9 @@ server.listen(80);
|
||||
<!-- YAML
|
||||
added: v8.4.0
|
||||
changes:
|
||||
+ - version: REPLACEME
|
||||
+ pr-url: https://github.com/nodejs-private/node-private/pull/250
|
||||
+ description: Added `unknownProtocolTimeout` option with a default of 10000.
|
||||
- version:
|
||||
- v12.18.0
|
||||
pr-url: https://github.com/nodejs-private/node-private/pull/206
|
||||
@@ -2178,6 +2190,10 @@ changes:
|
||||
servers, the identity options (`pfx` or `key`/`cert`) are usually required.
|
||||
* `origins` {string[]} An array of origin strings to send within an `ORIGIN`
|
||||
frame immediately following creation of a new server `Http2Session`.
|
||||
+ * `unknownProtocolTimeout` {number} Specifies a timeout in milliseconds that
|
||||
+ a server should wait when an [`'unknownProtocol'`][] event is emitted. If
|
||||
+ the socket has not been destroyed by that time the server will destroy it.
|
||||
+ **Default:** `10000`.
|
||||
* `onRequestHandler` {Function} See [Compatibility API][]
|
||||
* Returns: {Http2SecureServer}
|
||||
|
||||
@@ -2211,6 +2227,9 @@ server.listen(80);
|
||||
<!-- YAML
|
||||
added: v8.4.0
|
||||
changes:
|
||||
+ - version: REPLACEME
|
||||
+ pr-url: https://github.com/nodejs-private/node-private/pull/250
|
||||
+ description: Added `unknownProtocolTimeout` option with a default of 10000.
|
||||
- version:
|
||||
- v12.18.0
|
||||
pr-url: https://github.com/nodejs-private/node-private/pull/206
|
||||
@@ -2294,6 +2313,10 @@ changes:
|
||||
instance passed to `connect` and the `options` object, and returns any
|
||||
[`Duplex`][] stream that is to be used as the connection for this session.
|
||||
* ...: Any [`net.connect()`][] or [`tls.connect()`][] options can be provided.
|
||||
+ * `unknownProtocolTimeout` {number} Specifies a timeout in milliseconds that
|
||||
+ a server should wait when an [`'unknownProtocol'`][] event is emitted. If
|
||||
+ the socket has not been destroyed by that time the server will destroy it.
|
||||
+ **Default:** `10000`.
|
||||
* `listener` {Function} Will be registered as a one-time listener of the
|
||||
[`'connect'`][] event.
|
||||
* Returns: {ClientHttp2Session}
|
||||
diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js
|
||||
index 2116bc8..e9a63fe 100644
|
||||
--- a/lib/internal/http2/core.js
|
||||
+++ b/lib/internal/http2/core.js
|
||||
@@ -33,7 +33,7 @@ const net = require('net');
|
||||
const { Duplex } = require('stream');
|
||||
const tls = require('tls');
|
||||
const { URL } = require('url');
|
||||
-const { setImmediate } = require('timers');
|
||||
+const { setImmediate, setTimeout, clearTimeout } = require('timers');
|
||||
|
||||
const { kIncomingMessage } = require('_http_common');
|
||||
const { kServerResponse } = require('_http_server');
|
||||
@@ -2721,14 +2721,14 @@ function handleHeaderContinue(headers) {
|
||||
this.emit('continue');
|
||||
}
|
||||
|
||||
-const setTimeout = {
|
||||
+const setTimeoutValue = {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: setStreamTimeout
|
||||
};
|
||||
-ObjectDefineProperty(Http2Stream.prototype, 'setTimeout', setTimeout);
|
||||
-ObjectDefineProperty(Http2Session.prototype, 'setTimeout', setTimeout);
|
||||
+ObjectDefineProperty(Http2Stream.prototype, 'setTimeout', setTimeoutValue);
|
||||
+ObjectDefineProperty(Http2Session.prototype, 'setTimeout', setTimeoutValue);
|
||||
|
||||
|
||||
// When the socket emits an error, destroy the associated Http2Session and
|
||||
@@ -2788,6 +2788,22 @@ function connectionListener(socket) {
|
||||
debug('Unknown protocol from %s:%s',
|
||||
socket.remoteAddress, socket.remotePort);
|
||||
if (!this.emit('unknownProtocol', socket)) {
|
||||
+ debug('Unknown protocol timeout: %s', options.unknownProtocolTimeout);
|
||||
+ // Install a timeout if the socket was not successfully closed, then
|
||||
+ // destroy the socket to ensure that the underlying resources are
|
||||
+ // released.
|
||||
+ const timer = setTimeout(() => {
|
||||
+ if (!socket.destroyed) {
|
||||
+ debug('UnknownProtocol socket timeout, destroy socket');
|
||||
+ socket.destroy();
|
||||
+ }
|
||||
+ }, options.unknownProtocolTimeout);
|
||||
+ // Un-reference the timer to avoid blocking of application shutdown and
|
||||
+ // clear the timeout if the socket was successfully closed.
|
||||
+ timer.unref();
|
||||
+
|
||||
+ socket.once('close', () => clearTimeout(timer));
|
||||
+
|
||||
// We don't know what to do, so let's just tell the other side what's
|
||||
// going on in a format that they *might* understand.
|
||||
socket.end('HTTP/1.0 403 Forbidden\r\n' +
|
||||
@@ -2836,6 +2852,13 @@ function initializeOptions(options) {
|
||||
);
|
||||
}
|
||||
|
||||
+ if (options.unknownProtocolTimeout !== undefined)
|
||||
+ validateUint32(options.unknownProtocolTimeout, 'unknownProtocolTimeout');
|
||||
+ else
|
||||
+ // TODO(danbev): is this a good default value?
|
||||
+ options.unknownProtocolTimeout = 10000;
|
||||
+
|
||||
+
|
||||
// Used only with allowHTTP1
|
||||
options.Http1IncomingMessage = options.Http1IncomingMessage ||
|
||||
http.IncomingMessage;
|
||||
diff --git a/test/parallel/test-http2-server-unknown-protocol.js b/test/parallel/test-http2-server-unknown-protocol.js
|
||||
new file mode 100644
|
||||
index 0000000..639bbe4
|
||||
--- /dev/null
|
||||
+++ b/test/parallel/test-http2-server-unknown-protocol.js
|
||||
@@ -0,0 +1,33 @@
|
||||
+'use strict';
|
||||
+const common = require('../common');
|
||||
+const fixtures = require('../common/fixtures');
|
||||
+
|
||||
+// This test verifies that when a server receives an unknownProtocol it will
|
||||
+// not leave the socket open if the client does not close it.
|
||||
+
|
||||
+if (!common.hasCrypto)
|
||||
+ common.skip('missing crypto');
|
||||
+
|
||||
+const h2 = require('http2');
|
||||
+const tls = require('tls');
|
||||
+
|
||||
+const server = h2.createSecureServer({
|
||||
+ key: fixtures.readKey('rsa_private.pem'),
|
||||
+ cert: fixtures.readKey('rsa_cert.crt'),
|
||||
+ unknownProtocolTimeout: 500,
|
||||
+ allowHalfOpen: true
|
||||
+});
|
||||
+
|
||||
+server.on('connection', (socket) => {
|
||||
+ socket.on('close', common.mustCall(() => {
|
||||
+ server.close();
|
||||
+ }));
|
||||
+});
|
||||
+
|
||||
+server.listen(0, function() {
|
||||
+ tls.connect({
|
||||
+ port: server.address().port,
|
||||
+ rejectUnauthorized: false,
|
||||
+ ALPNProtocols: ['bogus']
|
||||
+ });
|
||||
+});
|
||||
--
|
||||
2.23.0
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
From 1564752d553f582c8048ee45614f870ee2a446c9 Mon Sep 17 00:00:00 2001
|
||||
From: Matteo Collina <hello@matteocollina.com>
|
||||
Date: Thu, 14 Jan 2021 16:04:44 +0100
|
||||
Subject: [PATCH] src: drop localhost6 as allowed host for inspector
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
CVE-ID: CVE-2021-22884
|
||||
Refs: https://hackerone.com/bugs?report_id=1069487
|
||||
PR-URL: https://github.com/nodejs/node/pull/244
|
||||
Reviewed-By: Beth Griggs <bgriggs@redhat.com>
|
||||
Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com>
|
||||
Reviewed-By: Mary Marchini <oss@mmarchini.me>
|
||||
Reviewed-By: Michael Dawson <midawson@redhat.com>
|
||||
Reviewed-By: Michaël Zasso <targos@protonmail.com>
|
||||
Reviewed-By: Rich Trott <rtrott@gmail.com>
|
||||
Reference: https://github.com/nodejs/node/commit/1564752d553f582c8048ee45614f870ee2a446c9
|
||||
---
|
||||
src/inspector_socket.cc | 3 +--
|
||||
1 file changed, 1 insertion(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/inspector_socket.cc b/src/inspector_socket.cc
|
||||
index a701928..3814565 100644
|
||||
--- a/src/inspector_socket.cc
|
||||
+++ b/src/inspector_socket.cc
|
||||
@@ -584,8 +584,7 @@ class HttpHandler : public ProtocolHandler {
|
||||
bool IsAllowedHost(const std::string& host_with_port) const {
|
||||
std::string host = TrimPort(host_with_port);
|
||||
return host.empty() || IsIPAddress(host)
|
||||
- || node::StringEqualNoCase(host.data(), "localhost")
|
||||
- || node::StringEqualNoCase(host.data(), "localhost6");
|
||||
+ || node::StringEqualNoCase(host.data(), "localhost");
|
||||
}
|
||||
|
||||
bool parsing_value_;
|
||||
--
|
||||
2.23.0
|
||||
@ -1,177 +0,0 @@
|
||||
From d33aead28bcec32a2a450f884907a6d971631829 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Noordhuis <info@bnoordhuis.nl>
|
||||
Date: Fri, 21 May 2021 11:23:36 +0200
|
||||
Subject: [PATCH] deps: uv: cherry-pick 99c29c9c2c9b
|
||||
|
||||
Original commit message:
|
||||
|
||||
idna: fix OOB read in punycode decoder
|
||||
|
||||
Reported by Eric Sesterhenn in collaboration with
|
||||
Cure53 and ExpressVPN.
|
||||
|
||||
Deleted unintroduced test files.
|
||||
|
||||
Reported-By: Eric Sesterhenn <eric.sesterhenn@x41-dsec.de>
|
||||
PR-URL: https://github.com/libuv/libuv-private/pull/1
|
||||
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
|
||||
Reviewed-By: Richard Lau <rlau@redhat.com>
|
||||
|
||||
CVE-ID: CVE-2021-22918
|
||||
Refs: https://hackerone.com/reports/1209681
|
||||
PR-URL: https://github.com/nodejs-private/node-private/pull/267
|
||||
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
|
||||
Reviewed-By: Richard Lau <rlau@redhat.com>
|
||||
Reviewed-By: Michael Dawson <midawson@redhat.com>
|
||||
Reviewed-By: Beth Griggs <bgriggs@redhat.com>
|
||||
---
|
||||
deps/uv/src/idna.c | 49 ++++++++++++++++++++++++++++++++++------------
|
||||
1 file changed, 36 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/deps/uv/src/idna.c b/deps/uv/src/idna.c
|
||||
index 13ffac6..b44cb16 100644
|
||||
--- a/deps/uv/src/idna.c
|
||||
+++ b/deps/uv/src/idna.c
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "uv.h"
|
||||
#include "idna.h"
|
||||
+#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static unsigned uv__utf8_decode1_slow(const char** p,
|
||||
@@ -32,7 +33,7 @@ static unsigned uv__utf8_decode1_slow(const char** p,
|
||||
if (a > 0xF7)
|
||||
return -1;
|
||||
|
||||
- switch (*p - pe) {
|
||||
+ switch (pe - *p) {
|
||||
default:
|
||||
if (a > 0xEF) {
|
||||
min = 0x10000;
|
||||
@@ -62,6 +63,8 @@ static unsigned uv__utf8_decode1_slow(const char** p,
|
||||
a = 0;
|
||||
break;
|
||||
}
|
||||
+ /* Fall through. */
|
||||
+ case 0:
|
||||
return -1; /* Invalid continuation byte. */
|
||||
}
|
||||
|
||||
@@ -88,6 +91,8 @@ static unsigned uv__utf8_decode1_slow(const char** p,
|
||||
unsigned uv__utf8_decode1(const char** p, const char* pe) {
|
||||
unsigned a;
|
||||
|
||||
+ assert(*p < pe);
|
||||
+
|
||||
a = (unsigned char) *(*p)++;
|
||||
|
||||
if (a < 128)
|
||||
@@ -96,9 +101,6 @@ unsigned uv__utf8_decode1(const char** p, const char* pe) {
|
||||
return uv__utf8_decode1_slow(p, pe, a);
|
||||
}
|
||||
|
||||
-#define foreach_codepoint(c, p, pe) \
|
||||
- for (; (void) (*p <= pe && (c = uv__utf8_decode1(p, pe))), *p <= pe;)
|
||||
-
|
||||
static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
char** d, char* de) {
|
||||
static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
@@ -121,15 +123,22 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
ss = s;
|
||||
todo = 0;
|
||||
|
||||
- foreach_codepoint(c, &s, se) {
|
||||
+ /* Note: after this loop we've visited all UTF-8 characters and know
|
||||
+ * they're legal so we no longer need to check for decode errors.
|
||||
+ */
|
||||
+ while (s < se) {
|
||||
+ c = uv__utf8_decode1(&s, se);
|
||||
+
|
||||
+ if (c == -1u)
|
||||
+ return UV_EINVAL;
|
||||
+
|
||||
if (c < 128)
|
||||
h++;
|
||||
- else if (c == (unsigned) -1)
|
||||
- return UV_EINVAL;
|
||||
else
|
||||
todo++;
|
||||
}
|
||||
|
||||
+ /* Only write "xn--" when there are non-ASCII characters. */
|
||||
if (todo > 0) {
|
||||
if (*d < de) *(*d)++ = 'x';
|
||||
if (*d < de) *(*d)++ = 'n';
|
||||
@@ -137,9 +146,13 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
if (*d < de) *(*d)++ = '-';
|
||||
}
|
||||
|
||||
+ /* Write ASCII characters. */
|
||||
x = 0;
|
||||
s = ss;
|
||||
- foreach_codepoint(c, &s, se) {
|
||||
+ while (s < se) {
|
||||
+ c = uv__utf8_decode1(&s, se);
|
||||
+ assert(c != -1u);
|
||||
+
|
||||
if (c > 127)
|
||||
continue;
|
||||
|
||||
@@ -166,10 +179,15 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
while (todo > 0) {
|
||||
m = -1;
|
||||
s = ss;
|
||||
- foreach_codepoint(c, &s, se)
|
||||
+
|
||||
+ while (s < se) {
|
||||
+ c = uv__utf8_decode1(&s, se);
|
||||
+ assert(c != -1u);
|
||||
+
|
||||
if (c >= n)
|
||||
if (c < m)
|
||||
m = c;
|
||||
+ }
|
||||
|
||||
x = m - n;
|
||||
y = h + 1;
|
||||
@@ -181,7 +199,10 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
n = m;
|
||||
|
||||
s = ss;
|
||||
- foreach_codepoint(c, &s, se) {
|
||||
+ while (s < se) {
|
||||
+ c = uv__utf8_decode1(&s, se);
|
||||
+ assert(c != -1u);
|
||||
+
|
||||
if (c < n)
|
||||
if (++delta == 0)
|
||||
return UV_E2BIG; /* Overflow. */
|
||||
@@ -245,8 +266,6 @@ static int uv__idna_toascii_label(const char* s, const char* se,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#undef foreach_codepoint
|
||||
-
|
||||
long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
|
||||
const char* si;
|
||||
const char* st;
|
||||
@@ -256,10 +275,14 @@ long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
|
||||
|
||||
ds = d;
|
||||
|
||||
- for (si = s; si < se; /* empty */) {
|
||||
+ si = s;
|
||||
+ while (si < se) {
|
||||
st = si;
|
||||
c = uv__utf8_decode1(&si, se);
|
||||
|
||||
+ if (c == -1u)
|
||||
+ return UV_EINVAL;
|
||||
+
|
||||
if (c != '.')
|
||||
if (c != 0x3002) /* 。 */
|
||||
if (c != 0xFF0E) /* . */
|
||||
--
|
||||
2.27.0
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
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();
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
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
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
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));
|
||||
+});
|
||||
Binary file not shown.
43
nodejs.spec
43
nodejs.spec
@ -1,10 +1,10 @@
|
||||
%bcond_with bootstrap
|
||||
%global baserelease 7
|
||||
%global baserelease 1
|
||||
%{?!_pkgdocdir:%global _pkgdocdir %{_docdir}/%{name}-%{version}}
|
||||
%global nodejs_epoch 1
|
||||
%global nodejs_major 12
|
||||
%global nodejs_minor 18
|
||||
%global nodejs_patch 4
|
||||
%global nodejs_minor 22
|
||||
%global nodejs_patch 11
|
||||
%global nodejs_abi %{nodejs_major}.%{nodejs_minor}
|
||||
%global nodejs_soversion 72
|
||||
%global nodejs_version %{nodejs_major}.%{nodejs_minor}.%{nodejs_patch}
|
||||
@ -19,19 +19,19 @@
|
||||
%global v8_version %{v8_major}.%{v8_minor}.%{v8_build}.%{v8_patch}
|
||||
%global v8_release %{nodejs_epoch}.%{nodejs_major}.%{nodejs_minor}.%{nodejs_patch}.%{nodejs_release}
|
||||
%global c_ares_major 1
|
||||
%global c_ares_minor 16
|
||||
%global c_ares_patch 0
|
||||
%global c_ares_minor 18
|
||||
%global c_ares_patch 1
|
||||
%global c_ares_version %{c_ares_major}.%{c_ares_minor}.%{c_ares_patch}
|
||||
%global http_parser_major 2
|
||||
%global http_parser_minor 9
|
||||
%global http_parser_patch 3
|
||||
%global http_parser_patch 4
|
||||
%global http_parser_version %{http_parser_major}.%{http_parser_minor}.%{http_parser_patch}
|
||||
%global llhttp_major 2
|
||||
%global llhttp_minor 1
|
||||
%global llhttp_patch 2
|
||||
%global llhttp_patch 4
|
||||
%global llhttp_version %{llhttp_major}.%{llhttp_minor}.%{llhttp_patch}
|
||||
%global libuv_major 1
|
||||
%global libuv_minor 38
|
||||
%global libuv_minor 40
|
||||
%global libuv_patch 0
|
||||
%global libuv_version %{libuv_major}.%{libuv_minor}.%{libuv_patch}
|
||||
%global nghttp2_major 1
|
||||
@ -52,11 +52,11 @@
|
||||
%global npm_epoch 1
|
||||
%global npm_major 6
|
||||
%global npm_minor 14
|
||||
%global npm_patch 6
|
||||
%global npm_patch 16
|
||||
%global npm_version %{npm_major}.%{npm_minor}.%{npm_patch}
|
||||
%global uvwasi_major 0
|
||||
%global uvwasi_minor 0
|
||||
%global uvwasi_patch 9
|
||||
%global uvwasi_patch 11
|
||||
%global uvwasi_version %{uvwasi_major}.%{uvwasi_minor}.%{uvwasi_patch}
|
||||
%global histogram_major 0
|
||||
%global histogram_minor 9
|
||||
@ -81,20 +81,8 @@ Source7: nodejs_native.attr
|
||||
|
||||
Patch0001: 0001-Disable-running-gyp-on-shared-deps.patch
|
||||
Patch0002: 0002-Install-both-binaries-and-use-libdir.patch
|
||||
%ifarch aarch64
|
||||
Patch0003: 0003-Modify-openEuler-aarch64-v8_os_page_size-to-64.patch
|
||||
%endif
|
||||
Patch0004: 0004-Make-AARCH64-compile-on-64KB-physical-pages.patch
|
||||
Patch0005: CVE-2020-8265.patch
|
||||
Patch0006: CVE-2020-8287-1.patch
|
||||
Patch0007: CVE-2020-8287-2.patch
|
||||
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
|
||||
Patch0003: 0004-Make-AARCH64-compile-on-64KB-physical-pages.patch
|
||||
Patch00010: 0005-use-getauxval-in-node_main_cc.patch
|
||||
|
||||
BuildRequires: python3-devel
|
||||
BuildRequires: zlib-devel
|
||||
@ -196,7 +184,7 @@ package to save space if non-English locales are not needed.
|
||||
Summary: v8 - development headers
|
||||
Epoch: %{v8_epoch}
|
||||
Version: %{v8_version}
|
||||
Release: %{v8_release}%{?dist}
|
||||
Release: %{v8_release}
|
||||
Requires: %{name}-devel%{?_isa} = %{nodejs_epoch}:%{nodejs_version}-%{nodejs_release}%{?dist}
|
||||
|
||||
%description -n v8-devel
|
||||
@ -206,7 +194,7 @@ Development headers for the v8 runtime.
|
||||
Summary: Node.js Package Manager
|
||||
Epoch: %{npm_epoch}
|
||||
Version: %{npm_version}
|
||||
Release: %{npm_release}%{?dist}
|
||||
Release: %{npm_release}
|
||||
|
||||
Obsoletes: npm < 0:3.5.4-6
|
||||
Provides: npm = %{npm_epoch}:%{npm_version}
|
||||
@ -497,6 +485,9 @@ end
|
||||
%{_pkgdocdir}/npm/docs
|
||||
|
||||
%changelog
|
||||
* Mon Mar 28 2022 wangkai <wangkai385@huawei.com> 1:12.22.11-1
|
||||
- Update to 12.22.11, fix some cves.
|
||||
|
||||
* Thu Oct 21 2021 yaoxin <yaoxin30@huawei.com> - 1:12.18.4-7
|
||||
- fix CVE-2021-22930
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user