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