File CVE-2020-8174.patch of Package nodejs8.15384

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-v8.17.0/src/node_api.cc
===================================================================
--- node-v8.17.0.orig/src/node_api.cc
+++ node-v8.17.0/src/node_api.cc
@@ -2625,7 +2625,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);
@@ -2634,6 +2634,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);
@@ -2661,7 +2663,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);
@@ -2670,6 +2672,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);
@@ -2698,7 +2702,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);
@@ -2707,6 +2711,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-v8.17.0/test/addons-napi/test_string/test.js
===================================================================
--- node-v8.17.0.orig/test/addons-napi/test_string/test.js
+++ node-v8.17.0/test/addons-napi/test_string/test.js
@@ -81,3 +81,5 @@ assert.throws(() => {
 assert.throws(() => {
   test_string.TestLargeUtf16();
 }, /^Error: Invalid argument$/);
+
+test_string.TestMemoryCorruption(' '.repeat(64 * 1024));
Index: node-v8.17.0/test/addons-napi/test_string/test_string.c
===================================================================
--- node-v8.17.0.orig/test/addons-napi/test_string/test_string.c
+++ node-v8.17.0/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"
 
@@ -241,6 +242,25 @@ static napi_value TestLargeUtf16(napi_en
   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),
@@ -254,6 +274,7 @@ napi_value Init(napi_env env, napi_value
     DECLARE_NAPI_PROPERTY("TestLargeUtf8", TestLargeUtf8),
     DECLARE_NAPI_PROPERTY("TestLargeLatin1", TestLargeLatin1),
     DECLARE_NAPI_PROPERTY("TestLargeUtf16", TestLargeUtf16),
+    DECLARE_NAPI_PROPERTY("TestMemoryCorruption", TestMemoryCorruption),
   };
 
   NAPI_CALL(env, napi_define_properties(