2020-08-19 23:02:14 +02:00
|
|
|
/*
|
|
|
|
* 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());
|
2024-05-12 19:27:34 +02:00
|
|
|
cppgc::InitializeProcess(platform->GetPageAllocator());
|
2020-08-19 23:02:14 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|