Skip to content

Commit cd9827f

Browse files
tniessenBethGriggs
authored andcommittedJun 2, 2020
napi: fix memory corruption vulnerability
Fixes: https://hackerone.com/reports/784186 CVE-ID: CVE-2020-8174 PR-URL: nodejs-private/node-private#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>
1 parent ef2df69 commit cd9827f

File tree

3 files changed

+31
-3
lines changed

3 files changed

+31
-3
lines changed
 

‎src/node_api.cc

+9-3
Original file line numberDiff line numberDiff line change
@@ -2889,7 +2889,7 @@ napi_status napi_get_value_string_latin1(napi_env env,
28892889
if (!buf) {
28902890
CHECK_ARG(env, result);
28912891
*result = val.As<v8::String>()->Length();
2892-
} else {
2892+
} else if (bufsize != 0) {
28932893
int copied =
28942894
val.As<v8::String>()->WriteOneByte(env->isolate,
28952895
reinterpret_cast<uint8_t*>(buf),
@@ -2901,6 +2901,8 @@ napi_status napi_get_value_string_latin1(napi_env env,
29012901
if (result != nullptr) {
29022902
*result = copied;
29032903
}
2904+
} else if (result != nullptr) {
2905+
*result = 0;
29042906
}
29052907

29062908
return napi_clear_last_error(env);
@@ -2928,7 +2930,7 @@ napi_status napi_get_value_string_utf8(napi_env env,
29282930
if (!buf) {
29292931
CHECK_ARG(env, result);
29302932
*result = val.As<v8::String>()->Utf8Length(env->isolate);
2931-
} else {
2933+
} else if (bufsize != 0) {
29322934
int copied = val.As<v8::String>()->WriteUtf8(
29332935
env->isolate,
29342936
buf,
@@ -2940,6 +2942,8 @@ napi_status napi_get_value_string_utf8(napi_env env,
29402942
if (result != nullptr) {
29412943
*result = copied;
29422944
}
2945+
} else if (result != nullptr) {
2946+
*result = 0;
29432947
}
29442948

29452949
return napi_clear_last_error(env);
@@ -2968,7 +2972,7 @@ napi_status napi_get_value_string_utf16(napi_env env,
29682972
CHECK_ARG(env, result);
29692973
// V8 assumes UTF-16 length is the same as the number of characters.
29702974
*result = val.As<v8::String>()->Length();
2971-
} else {
2975+
} else if (bufsize != 0) {
29722976
int copied = val.As<v8::String>()->Write(env->isolate,
29732977
reinterpret_cast<uint16_t*>(buf),
29742978
0,
@@ -2979,6 +2983,8 @@ napi_status napi_get_value_string_utf16(napi_env env,
29792983
if (result != nullptr) {
29802984
*result = copied;
29812985
}
2986+
} else if (result != nullptr) {
2987+
*result = 0;
29822988
}
29832989

29842990
return napi_clear_last_error(env);

‎test/addons-napi/test_string/test.js

+2
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,5 @@ assert.throws(() => {
8181
assert.throws(() => {
8282
test_string.TestLargeUtf16();
8383
}, /^Error: Invalid argument$/);
84+
85+
test_string.TestMemoryCorruption(' '.repeat(64 * 1024));

‎test/addons-napi/test_string/test_string.c

+20
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <limits.h> // INT_MAX
2+
#include <string.h>
23
#include <node_api.h>
34
#include "../common.h"
45

@@ -244,6 +245,24 @@ static napi_value TestLargeUtf16(napi_env env, napi_callback_info info) {
244245
return output;
245246
}
246247

248+
static napi_value TestMemoryCorruption(napi_env env, napi_callback_info info) {
249+
size_t argc = 1;
250+
napi_value args[1];
251+
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
252+
253+
NAPI_ASSERT(env, argc == 1, "Wrong number of arguments");
254+
255+
char buf[10] = { 0 };
256+
NAPI_CALL(env, napi_get_value_string_utf8(env, args[0], buf, 0, NULL));
257+
258+
char zero[10] = { 0 };
259+
if (memcmp(buf, zero, sizeof(buf)) != 0) {
260+
NAPI_CALL(env, napi_throw_error(env, NULL, "Buffer overwritten"));
261+
}
262+
263+
return NULL;
264+
}
265+
247266
static napi_value Init(napi_env env, napi_value exports) {
248267
napi_property_descriptor properties[] = {
249268
DECLARE_NAPI_PROPERTY("TestLatin1", TestLatin1),
@@ -257,6 +276,7 @@ static napi_value Init(napi_env env, napi_value exports) {
257276
DECLARE_NAPI_PROPERTY("TestLargeUtf8", TestLargeUtf8),
258277
DECLARE_NAPI_PROPERTY("TestLargeLatin1", TestLargeLatin1),
259278
DECLARE_NAPI_PROPERTY("TestLargeUtf16", TestLargeUtf16),
279+
DECLARE_NAPI_PROPERTY("TestMemoryCorruption", TestMemoryCorruption),
260280
};
261281

262282
NAPI_CALL(env, napi_define_properties(

0 commit comments

Comments
 (0)
Please sign in to comment.