* napi: fix various types of memory corruption in napi_get_value_string_*() (CVE-2020-8174, bsc#1172443) * http2: fix HTTP/2 Large Settings Frame DoS (CVE-2020-11080, bsc#1172442) * TLS session reuse can lead to host certificate verification bypass (CVE-2020-8172, bsc#1172441) OBS-URL: https://build.opensuse.org/package/show/devel:languages:nodejs/nodejs6?expand=0&rev=123
135 lines
4.7 KiB
Diff
135 lines
4.7 KiB
Diff
Backported from
|
|
|
|
From cd9827f1054b0b24d1d015daf8ed2b4e78eb8e4d Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= <tniessen@tnie.de>
|
|
Date: Tue, 21 Apr 2020 10:21:29 -0700
|
|
Subject: [PATCH] napi: fix memory corruption vulnerability
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Fixes: https://hackerone.com/reports/784186
|
|
CVE-ID: CVE-2020-8174
|
|
PR-URL: https://github.com/nodejs-private/node-private/pull/203
|
|
Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com>
|
|
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
|
|
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
|
|
---
|
|
src/node_api.cc | 12 +++++++++---
|
|
test/addons-napi/test_string/test.js | 2 ++
|
|
test/addons-napi/test_string/test_string.c | 20 ++++++++++++++++++++
|
|
3 files changed, 31 insertions(+), 3 deletions(-)
|
|
|
|
Index: node-v6.17.1/src/node_api.cc
|
|
===================================================================
|
|
--- node-v6.17.1.orig/src/node_api.cc
|
|
+++ node-v6.17.1/src/node_api.cc
|
|
@@ -2253,7 +2253,7 @@ napi_status napi_get_value_string_latin1
|
|
if (!buf) {
|
|
CHECK_ARG(env, result);
|
|
*result = val.As<v8::String>()->Length();
|
|
- } else {
|
|
+ } else if (bufsize != 0) {
|
|
int copied = val.As<v8::String>()->WriteOneByte(
|
|
reinterpret_cast<uint8_t*>(buf), 0, bufsize - 1,
|
|
v8::String::NO_NULL_TERMINATION);
|
|
@@ -2262,6 +2262,8 @@ napi_status napi_get_value_string_latin1
|
|
if (result != nullptr) {
|
|
*result = copied;
|
|
}
|
|
+ } else if (result != nullptr) {
|
|
+ *result = 0;
|
|
}
|
|
|
|
return napi_clear_last_error(env);
|
|
@@ -2289,7 +2291,7 @@ napi_status napi_get_value_string_utf8(n
|
|
if (!buf) {
|
|
CHECK_ARG(env, result);
|
|
*result = val.As<v8::String>()->Utf8Length();
|
|
- } else {
|
|
+ } else if (bufsize != 0) {
|
|
int copied = val.As<v8::String>()->WriteUtf8(
|
|
buf, bufsize - 1, nullptr, v8::String::REPLACE_INVALID_UTF8 |
|
|
v8::String::NO_NULL_TERMINATION);
|
|
@@ -2298,6 +2300,8 @@ napi_status napi_get_value_string_utf8(n
|
|
if (result != nullptr) {
|
|
*result = copied;
|
|
}
|
|
+ } else if (result != nullptr) {
|
|
+ *result = 0;
|
|
}
|
|
|
|
return napi_clear_last_error(env);
|
|
@@ -2326,7 +2330,7 @@ napi_status napi_get_value_string_utf16(
|
|
CHECK_ARG(env, result);
|
|
// V8 assumes UTF-16 length is the same as the number of characters.
|
|
*result = val.As<v8::String>()->Length();
|
|
- } else {
|
|
+ } else if (bufsize != 0) {
|
|
int copied = val.As<v8::String>()->Write(
|
|
reinterpret_cast<uint16_t*>(buf), 0, bufsize - 1,
|
|
v8::String::NO_NULL_TERMINATION);
|
|
@@ -2335,6 +2339,8 @@ napi_status napi_get_value_string_utf16(
|
|
if (result != nullptr) {
|
|
*result = copied;
|
|
}
|
|
+ } else if (result != nullptr) {
|
|
+ *result = 0;
|
|
}
|
|
|
|
return napi_clear_last_error(env);
|
|
Index: node-v6.17.1/test/addons-napi/test_string/test.js
|
|
===================================================================
|
|
--- node-v6.17.1.orig/test/addons-napi/test_string/test.js
|
|
+++ node-v6.17.1/test/addons-napi/test_string/test.js
|
|
@@ -73,3 +73,5 @@ assert.strictEqual(test_string.Utf8Lengt
|
|
assert.throws(() => {
|
|
test_string.TestLargeUtf8();
|
|
}, /^Error: Invalid argument$/);
|
|
+
|
|
+test_string.TestMemoryCorruption(' '.repeat(64 * 1024));
|
|
Index: node-v6.17.1/test/addons-napi/test_string/test_string.c
|
|
===================================================================
|
|
--- node-v6.17.1.orig/test/addons-napi/test_string/test_string.c
|
|
+++ node-v6.17.1/test/addons-napi/test_string/test_string.c
|
|
@@ -1,4 +1,5 @@
|
|
#include <limits.h> // INT_MAX
|
|
+#include <string.h>
|
|
#include <node_api.h>
|
|
#include "../common.h"
|
|
|
|
@@ -215,6 +216,25 @@ napi_value TestLargeUtf8(napi_env env, n
|
|
return output;
|
|
}
|
|
|
|
+static napi_value TestMemoryCorruption(napi_env env, napi_callback_info info) {
|
|
+ size_t argc = 1;
|
|
+ napi_value args[1];
|
|
+ NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
|
|
+
|
|
+ NAPI_ASSERT(env, argc == 1, "Wrong number of arguments");
|
|
+
|
|
+ char buf[10] = { 0 };
|
|
+ NAPI_CALL(env, napi_get_value_string_utf8(env, args[0], buf, 0, NULL));
|
|
+
|
|
+ char zero[10] = { 0 };
|
|
+ if (memcmp(buf, zero, sizeof(buf)) != 0) {
|
|
+ NAPI_CALL(env, napi_throw_error(env, NULL, "Buffer overwritten"));
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+
|
|
napi_value Init(napi_env env, napi_value exports) {
|
|
napi_property_descriptor properties[] = {
|
|
DECLARE_NAPI_PROPERTY("TestLatin1", TestLatin1),
|
|
@@ -226,6 +246,7 @@ napi_value Init(napi_env env, napi_value
|
|
DECLARE_NAPI_PROPERTY("Utf16Length", Utf16Length),
|
|
DECLARE_NAPI_PROPERTY("Utf8Length", Utf8Length),
|
|
DECLARE_NAPI_PROPERTY("TestLargeUtf8", TestLargeUtf8),
|
|
+ DECLARE_NAPI_PROPERTY("TestMemoryCorruption", TestMemoryCorruption),
|
|
};
|
|
|
|
NAPI_CALL(env, napi_define_properties(
|