Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c676e52

Browse filesBrowse files
AdamKorcztargos
authored andcommitted
test: add fuzzer for native/js string conversion
Signed-off-by: Adam Korczynski <adam@adalogics.com> PR-URL: #51120 Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
1 parent 5f6415b commit c676e52
Copy full SHA for c676e52

File tree

Expand file treeCollapse file tree

2 files changed

+180
-0
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

2 files changed

+180
-0
lines changed
Open diff view settings
Collapse file

‎node.gyp‎

Copy file name to clipboardExpand all lines: node.gyp
+45Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,51 @@
11101110
}],
11111111
],
11121112
}, # fuzz_ClientHelloParser.cc
1113+
{ # fuzz_strings
1114+
'target_name': 'fuzz_strings',
1115+
'type': 'executable',
1116+
'dependencies': [
1117+
'<(node_lib_target_name)',
1118+
'deps/googletest/googletest.gyp:gtest_prod',
1119+
'deps/histogram/histogram.gyp:histogram',
1120+
'deps/uvwasi/uvwasi.gyp:uvwasi',
1121+
'deps/ada/ada.gyp:ada',
1122+
],
1123+
'includes': [
1124+
'node.gypi'
1125+
],
1126+
'include_dirs': [
1127+
'src',
1128+
'tools/msvs/genfiles',
1129+
'deps/v8/include',
1130+
'deps/cares/include',
1131+
'deps/uv/include',
1132+
'deps/uvwasi/include',
1133+
'test/cctest',
1134+
],
1135+
'defines': [
1136+
'NODE_ARCH="<(target_arch)"',
1137+
'NODE_PLATFORM="<(OS)"',
1138+
'NODE_WANT_INTERNALS=1',
1139+
],
1140+
'sources': [
1141+
'src/node_snapshot_stub.cc',
1142+
'test/fuzzers/fuzz_strings.cc',
1143+
],
1144+
'conditions': [
1145+
['OS=="linux"', {
1146+
'ldflags': [ '-fsanitize=fuzzer' ]
1147+
}],
1148+
# Ensure that ossfuzz flag has been set and that we are on Linux
1149+
[ 'OS!="linux" or ossfuzz!="true"', {
1150+
'type': 'none',
1151+
}],
1152+
# Avoid excessive LTO
1153+
['enable_lto=="true"', {
1154+
'ldflags': [ '-fno-lto' ],
1155+
}],
1156+
],
1157+
}, # fuzz_strings
11131158
{
11141159
'target_name': 'cctest',
11151160
'type': 'executable',
Collapse file

‎test/fuzzers/fuzz_strings.cc‎

Copy file name to clipboard
+135Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/*
2+
* A fuzzer focused on C string -> Javascript String.
3+
*/
4+
5+
#include <stdlib.h>
6+
#include "js_native_api.h"
7+
#include "js_native_api_v8.h"
8+
#include "node.h"
9+
#include "node_platform.h"
10+
#include "node_internals.h"
11+
#include "node_api_internals.h"
12+
#include "node_url.h"
13+
#include "env-inl.h"
14+
#include "util-inl.h"
15+
#include "v8.h"
16+
#include "libplatform/libplatform.h"
17+
#include "aliased_buffer.h"
18+
#include "fuzz_helper.h"
19+
20+
using node::AliasedBufferBase;
21+
22+
/* General set up */
23+
using ArrayBufferUniquePtr = std::unique_ptr<node::ArrayBufferAllocator,
24+
decltype(&node::FreeArrayBufferAllocator)>;
25+
using TracingAgentUniquePtr = std::unique_ptr<node::tracing::Agent>;
26+
using NodePlatformUniquePtr = std::unique_ptr<node::NodePlatform>;
27+
28+
static TracingAgentUniquePtr tracing_agent;
29+
static NodePlatformUniquePtr platform;
30+
static uv_loop_t current_loop;
31+
static napi_env addon_env;
32+
33+
inline napi_env NewEnv(v8::Local<v8::Context> context,
34+
const std::string& module_filename,
35+
int32_t module_api_version) ;
36+
37+
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
38+
uv_os_unsetenv("NODE_OPTIONS");
39+
std::vector<std::string> node_argv{ "fuzz_string_conversion" };
40+
std::vector<std::string> exec_argv;
41+
std::vector<std::string> errors;
42+
43+
node::InitializeNodeWithArgs(&node_argv, &exec_argv, &errors);
44+
45+
tracing_agent = std::make_unique<node::tracing::Agent>();
46+
node::tracing::TraceEventHelper::SetAgent(tracing_agent.get());
47+
node::tracing::TracingController* tracing_controller =
48+
tracing_agent->GetTracingController();
49+
CHECK_EQ(0, uv_loop_init(&current_loop));
50+
static constexpr int kV8ThreadPoolSize = 4;
51+
platform.reset(
52+
new node::NodePlatform(kV8ThreadPoolSize, tracing_controller));
53+
v8::V8::InitializePlatform(platform.get());
54+
cppgc::InitializeProcess(platform->GetPageAllocator());
55+
v8::V8::Initialize();
56+
return 0;
57+
}
58+
59+
class FuzzerFixtureHelper {
60+
public:
61+
v8::Isolate* isolate_;
62+
ArrayBufferUniquePtr allocator;
63+
64+
FuzzerFixtureHelper()
65+
: allocator(ArrayBufferUniquePtr(node::CreateArrayBufferAllocator(),
66+
&node::FreeArrayBufferAllocator)) {
67+
isolate_ = NewIsolate(allocator.get(), &current_loop, platform.get());
68+
CHECK_NOT_NULL(isolate_);
69+
isolate_->Enter();
70+
};
71+
72+
void Teardown() {
73+
platform->DrainTasks(isolate_);
74+
isolate_->Exit();
75+
platform->UnregisterIsolate(isolate_);
76+
isolate_->Dispose();
77+
isolate_ = nullptr;
78+
}
79+
};
80+
81+
void EnvTest(v8::Isolate* isolate_, char* env_string, size_t size) {
82+
const v8::HandleScope handle_scope(isolate_);
83+
Argv argv;
84+
85+
node::EnvironmentFlags::Flags flags = node::EnvironmentFlags::kDefaultFlags;
86+
auto isolate = handle_scope.GetIsolate();
87+
v8::Local<v8::Context> context_ = node::NewContext(isolate);
88+
context_->Enter();
89+
90+
node::IsolateData* isolate_data_ = node::CreateIsolateData(isolate, &current_loop,
91+
platform.get());
92+
std::vector<std::string> args(*argv, *argv + 1);
93+
std::vector<std::string> exec_args(*argv, *argv + 1);
94+
node::Environment* environment_ = node::CreateEnvironment(isolate_data_,
95+
context_, args, exec_args, flags);
96+
node::Environment* envi = environment_;
97+
SetProcessExitHandler(envi, [&](node::Environment* env_, int exit_code) {
98+
node::Stop(envi);
99+
});
100+
node::LoadEnvironment(envi, "");
101+
102+
103+
napi_addon_register_func init = [](napi_env env, napi_value exports) {
104+
addon_env = env;
105+
return exports;
106+
};
107+
v8::Local<v8::Object> module_obj = v8::Object::New(isolate);
108+
v8::Local<v8::Object> exports_obj = v8::Object::New(isolate);
109+
napi_module_register_by_symbol(
110+
exports_obj, module_obj, context_, init, NAPI_VERSION);
111+
size_t copied1, copied2;
112+
napi_value output1, output2;
113+
char *buf1 = (char *)malloc(size);
114+
char *buf2 = (char *)malloc(size);
115+
napi_create_string_utf8(addon_env, env_string, size, &output1);
116+
napi_get_value_string_utf8(addon_env, output1, buf1, size, &copied1);
117+
napi_create_string_latin1(addon_env, env_string, size, &output2);
118+
napi_get_value_string_latin1(addon_env, output2, buf2, size, &copied2);
119+
free(buf1);
120+
free(buf2);
121+
122+
// Cleanup!
123+
node::FreeEnvironment(environment_);
124+
node::FreeIsolateData(isolate_data_);
125+
context_->Exit();
126+
}
127+
128+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data2, size_t size) {
129+
FuzzerFixtureHelper ffh;
130+
std::string s(reinterpret_cast<const char*>(data2), size);
131+
EnvTest(ffh.isolate_, (char*)s.c_str(), size);
132+
ffh.Teardown();
133+
return 0;
134+
}
135+

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.