Coverage Report

Created: 2025-08-03 10:06

/src/node/test/fuzzers/fuzz_env.cc
Line
Count
Source
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
125k
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
31
125k
  uv_os_unsetenv("NODE_OPTIONS");
32
125k
  std::vector<std::string> node_argv{ "fuzz_env" };
33
125k
  std::vector<std::string> exec_argv;
34
125k
  std::vector<std::string> errors;
35
36
125k
  node::InitializeNodeWithArgs(&node_argv, &exec_argv, &errors);
37
38
125k
  tracing_agent = std::make_unique<node::tracing::Agent>();
39
125k
  node::tracing::TraceEventHelper::SetAgent(tracing_agent.get());
40
125k
  node::tracing::TracingController* tracing_controller =
41
125k
    tracing_agent->GetTracingController();  
42
125k
  CHECK_EQ(0, uv_loop_init(&current_loop));
43
125k
  static constexpr int kV8ThreadPoolSize = 4;
44
125k
  platform.reset(
45
125k
    new node::NodePlatform(kV8ThreadPoolSize, tracing_controller));
46
125k
  v8::V8::InitializePlatform(platform.get());
47
125k
  cppgc::InitializeProcess(platform->GetPageAllocator());
48
125k
  v8::V8::Initialize();
49
125k
  return 0;
50
125k
}
51
52
class FuzzerFixtureHelper {
53
public:
54
  v8::Isolate* isolate_;
55
  ArrayBufferUniquePtr allocator;
56
57
  FuzzerFixtureHelper()
58
126k
    : allocator(ArrayBufferUniquePtr(node::CreateArrayBufferAllocator(),
59
126k
                                     &node::FreeArrayBufferAllocator)) {
60
126k
    isolate_ = NewIsolate(allocator.get(), &current_loop, platform.get());
61
126k
    CHECK_NOT_NULL(isolate_);
62
126k
    isolate_->Enter();
63
126k
  };
64
65
126k
  void Teardown() {
66
126k
    platform->DrainTasks(isolate_);
67
126k
    isolate_->Exit();
68
126k
    platform->UnregisterIsolate(isolate_);
69
126k
    isolate_->Dispose();
70
126k
    isolate_ = nullptr;
71
126k
  }
72
};
73
74
109k
void EnvTest(v8::Isolate* isolate_, char* env_string) {
75
109k
  const v8::HandleScope handle_scope(isolate_);
76
109k
  Argv argv;
77
78
109k
  node::EnvironmentFlags::Flags flags = node::EnvironmentFlags::kDefaultFlags;
79
109k
  auto isolate = handle_scope.GetIsolate();
80
109k
  v8::Local<v8::Context> context_ = node::NewContext(isolate);
81
109k
  context_->Enter();
82
83
109k
  node::IsolateData* isolate_data_ = node::CreateIsolateData(isolate, &current_loop,
84
109k
                                                             platform.get());
85
109k
  std::vector<std::string> args(*argv, *argv + 1);
86
109k
  std::vector<std::string> exec_args(*argv, *argv + 1);
87
109k
  node::Environment* environment_ = node::CreateEnvironment(isolate_data_,
88
109k
                                          context_, args, exec_args, flags);
89
109k
  node::Environment* envi = environment_;
90
109k
  SetProcessExitHandler(envi, [&](node::Environment* env_, int exit_code) {
91
6.02k
    node::Stop(envi);
92
6.02k
  });
93
109k
  node::LoadEnvironment(envi, env_string);
94
95
  // Cleanup!
96
109k
  node::FreeEnvironment(environment_);
97
109k
  node::FreeIsolateData(isolate_data_);
98
109k
  context_->Exit();
99
109k
}
100
101
34.3k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data2, size_t size) {
102
34.3k
  FuzzerFixtureHelper ffh;
103
34.3k
  std::string s(reinterpret_cast<const char*>(data2), size);
104
34.3k
  EnvTest(ffh.isolate_, (char*)s.c_str());
105
34.3k
  ffh.Teardown();
106
34.3k
  return 0;
107
34.3k
}
108