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 f3a0457

Browse filesBrowse files
DavidKorczynskiMylesBorins
authored andcommitted
build: fuzzer that targets node::LoadEnvironment()
Refs: #34761 Refs: #33724 PR-URL: #34844 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Michael Dawson <midawson@redhat.com>
1 parent 42c4795 commit f3a0457
Copy full SHA for f3a0457

File tree

Expand file treeCollapse file tree

3 files changed

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

3 files changed

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

‎node.gyp‎

Copy file name to clipboardExpand all lines: node.gyp
+43Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,49 @@
11431143
}],
11441144
],
11451145
}, # fuzz_url
1146+
{ # fuzz_env
1147+
'target_name': 'fuzz_env',
1148+
'type': 'executable',
1149+
'dependencies': [
1150+
'<(node_lib_target_name)',
1151+
'deps/histogram/histogram.gyp:histogram',
1152+
'deps/uvwasi/uvwasi.gyp:uvwasi',
1153+
'node_dtrace_header',
1154+
'node_dtrace_ustack',
1155+
'node_dtrace_provider',
1156+
],
1157+
'includes': [
1158+
'node.gypi'
1159+
],
1160+
'include_dirs': [
1161+
'src',
1162+
'tools/msvs/genfiles',
1163+
'deps/v8/include',
1164+
'deps/cares/include',
1165+
'deps/uv/include',
1166+
'deps/uvwasi/include',
1167+
'test/cctest',
1168+
],
1169+
'defines': [
1170+
'NODE_ARCH="<(target_arch)"',
1171+
'NODE_PLATFORM="<(OS)"',
1172+
'NODE_WANT_INTERNALS=1',
1173+
],
1174+
'sources': [
1175+
'src/node_snapshot_stub.cc',
1176+
'src/node_code_cache_stub.cc',
1177+
'test/fuzzers/fuzz_env.cc',
1178+
],
1179+
'conditions': [
1180+
['OS=="linux"', {
1181+
'ldflags': [ '-fsanitize=fuzzer' ]
1182+
}],
1183+
# Ensure that ossfuzz flag has been set and that we are on Linux
1184+
[ 'OS!="linux" or ossfuzz!="true"', {
1185+
'type': 'none',
1186+
}],
1187+
],
1188+
}, # fuzz_env
11461189
{
11471190
'target_name': 'cctest',
11481191
'type': 'executable',
Collapse file

‎test/fuzzers/fuzz_env.cc‎

Copy file name to clipboard
+107Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* A fuzzer focused on the node::LoadEnvironment() function.
3+
*
4+
* Code here has been inspired by the cctest test case.
5+
*/
6+
7+
#include <stdlib.h>
8+
#include "node.h"
9+
#include "node_platform.h"
10+
#include "node_internals.h"
11+
#include "env-inl.h"
12+
#include "util-inl.h"
13+
#include "v8.h"
14+
#include "libplatform/libplatform.h"
15+
#include "aliased_buffer.h"
16+
#include "fuzz_helper.h"
17+
18+
using node::AliasedBufferBase;
19+
20+
/* General set up */
21+
using ArrayBufferUniquePtr = std::unique_ptr<node::ArrayBufferAllocator,
22+
decltype(&node::FreeArrayBufferAllocator)>;
23+
using TracingAgentUniquePtr = std::unique_ptr<node::tracing::Agent>;
24+
using NodePlatformUniquePtr = std::unique_ptr<node::NodePlatform>;
25+
26+
static TracingAgentUniquePtr tracing_agent;
27+
static NodePlatformUniquePtr platform;
28+
static uv_loop_t current_loop;
29+
30+
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
31+
uv_os_unsetenv("NODE_OPTIONS");
32+
std::vector<std::string> node_argv{ "fuzz_env" };
33+
std::vector<std::string> exec_argv;
34+
std::vector<std::string> errors;
35+
36+
node::InitializeNodeWithArgs(&node_argv, &exec_argv, &errors);
37+
38+
tracing_agent = std::make_unique<node::tracing::Agent>();
39+
node::tracing::TraceEventHelper::SetAgent(tracing_agent.get());
40+
node::tracing::TracingController* tracing_controller =
41+
tracing_agent->GetTracingController();
42+
CHECK_EQ(0, uv_loop_init(&current_loop));
43+
static constexpr int kV8ThreadPoolSize = 4;
44+
platform.reset(
45+
new node::NodePlatform(kV8ThreadPoolSize, tracing_controller));
46+
v8::V8::InitializePlatform(platform.get());
47+
v8::V8::Initialize();
48+
return 0;
49+
}
50+
51+
class FuzzerFixtureHelper {
52+
public:
53+
v8::Isolate* isolate_;
54+
ArrayBufferUniquePtr allocator;
55+
56+
FuzzerFixtureHelper()
57+
: allocator(ArrayBufferUniquePtr(node::CreateArrayBufferAllocator(),
58+
&node::FreeArrayBufferAllocator)) {
59+
isolate_ = NewIsolate(allocator.get(), &current_loop, platform.get());
60+
CHECK_NOT_NULL(isolate_);
61+
isolate_->Enter();
62+
};
63+
64+
void Teardown() {
65+
platform->DrainTasks(isolate_);
66+
isolate_->Exit();
67+
platform->UnregisterIsolate(isolate_);
68+
isolate_->Dispose();
69+
isolate_ = nullptr;
70+
}
71+
};
72+
73+
void EnvTest(v8::Isolate* isolate_, char* env_string) {
74+
const v8::HandleScope handle_scope(isolate_);
75+
Argv argv;
76+
77+
node::EnvironmentFlags::Flags flags = node::EnvironmentFlags::kDefaultFlags;
78+
auto isolate = handle_scope.GetIsolate();
79+
v8::Local<v8::Context> context_ = node::NewContext(isolate);
80+
context_->Enter();
81+
82+
node::IsolateData* isolate_data_ = node::CreateIsolateData(isolate, &current_loop,
83+
platform.get());
84+
std::vector<std::string> args(*argv, *argv + 1);
85+
std::vector<std::string> exec_args(*argv, *argv + 1);
86+
node::Environment* environment_ = node::CreateEnvironment(isolate_data_,
87+
context_, args, exec_args, flags);
88+
node::Environment* envi = environment_;
89+
SetProcessExitHandler(envi, [&](node::Environment* env_, int exit_code) {
90+
node::Stop(envi);
91+
});
92+
node::LoadEnvironment(envi, env_string);
93+
94+
// Cleanup!
95+
node::FreeEnvironment(environment_);
96+
node::FreeIsolateData(isolate_data_);
97+
context_->Exit();
98+
}
99+
100+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data2, size_t size) {
101+
FuzzerFixtureHelper ffh;
102+
std::string s(reinterpret_cast<const char*>(data2), size);
103+
EnvTest(ffh.isolate_, (char*)s.c_str());
104+
ffh.Teardown();
105+
return 0;
106+
}
107+
Collapse file

‎test/fuzzers/fuzz_helper.h‎

Copy file name to clipboard
+42Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
struct Argv {
2+
public:
3+
Argv() : Argv({"node", "-p", "process.version"}) {}
4+
5+
Argv(const std::initializer_list<const char*> &args) {
6+
nr_args_ = args.size();
7+
int total_len = 0;
8+
for (auto it = args.begin(); it != args.end(); ++it) {
9+
total_len += strlen(*it) + 1;
10+
}
11+
argv_ = static_cast<char**>(malloc(nr_args_ * sizeof(char*)));
12+
argv_[0] = static_cast<char*>(malloc(total_len));
13+
int i = 0;
14+
int offset = 0;
15+
for (auto it = args.begin(); it != args.end(); ++it, ++i) {
16+
int len = strlen(*it) + 1;
17+
snprintf(argv_[0] + offset, len, "%s", *it);
18+
// Skip argv_[0] as it points the correct location already
19+
if (i > 0) {
20+
argv_[i] = argv_[0] + offset;
21+
}
22+
offset += len;
23+
}
24+
}
25+
26+
~Argv() {
27+
free(argv_[0]);
28+
free(argv_);
29+
}
30+
31+
int nr_args() const {
32+
return nr_args_;
33+
}
34+
35+
char** operator*() const {
36+
return argv_;
37+
}
38+
39+
private:
40+
char** argv_;
41+
int nr_args_;
42+
};

0 commit comments

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