Coverage Report

Created: 2025-07-04 09:33

/src/node/test/fuzzers/fuzz_ParseGeneralReply.cc
Line
Count
Source (jump to first uncovered line)
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 "ares_nameser.h"
12
#include "crypto/crypto_bio.h"
13
#include "crypto/crypto_context.h"
14
#include "cares_wrap.h"
15
#include "env-inl.h"
16
#include "util-inl.h"
17
#include "v8.h"
18
#include "libplatform/libplatform.h"
19
#include "aliased_buffer.h"
20
#include "fuzz_helper.h"
21
22
23
using node::AliasedBufferBase;
24
using v8::Array;
25
26
/*int ParseSrvReply(
27
    node::Environment* env,
28
    const unsigned char* buf,
29
    int len,
30
    v8::Local<Array> ret,
31
    bool need_type = false);*/
32
33
/* General set up */
34
using ArrayBufferUniquePtr = std::unique_ptr<node::ArrayBufferAllocator,
35
  decltype(&node::FreeArrayBufferAllocator)>;
36
using TracingAgentUniquePtr = std::unique_ptr<node::tracing::Agent>;
37
using NodePlatformUniquePtr = std::unique_ptr<node::NodePlatform>;
38
39
static TracingAgentUniquePtr tracing_agent;
40
static NodePlatformUniquePtr platform;
41
static uv_loop_t current_loop;
42
43
132k
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
44
132k
  uv_os_unsetenv("NODE_OPTIONS");
45
132k
  std::vector<std::string> node_argv{ "fuzz_env" };
46
132k
  std::vector<std::string> exec_argv;
47
132k
  std::vector<std::string> errors;
48
49
132k
  node::InitializeNodeWithArgs(&node_argv, &exec_argv, &errors);
50
51
132k
  tracing_agent = std::make_unique<node::tracing::Agent>();
52
132k
  node::tracing::TraceEventHelper::SetAgent(tracing_agent.get());
53
132k
  node::tracing::TracingController* tracing_controller =
54
132k
    tracing_agent->GetTracingController();  
55
132k
  CHECK_EQ(0, uv_loop_init(&current_loop));
56
132k
  static constexpr int kV8ThreadPoolSize = 4;
57
132k
  platform.reset(
58
132k
    new node::NodePlatform(kV8ThreadPoolSize, tracing_controller));
59
132k
  v8::V8::InitializePlatform(platform.get());
60
132k
  cppgc::InitializeProcess(platform->GetPageAllocator());
61
132k
  v8::V8::Initialize();
62
132k
  return 0;
63
132k
}
64
65
class FuzzerFixtureHelper {
66
public:
67
  v8::Isolate* isolate_;
68
  ArrayBufferUniquePtr allocator;
69
70
  FuzzerFixtureHelper()
71
134k
    : allocator(ArrayBufferUniquePtr(node::CreateArrayBufferAllocator(),
72
134k
                                     &node::FreeArrayBufferAllocator)) {
73
134k
    isolate_ = NewIsolate(allocator.get(), &current_loop, platform.get());
74
134k
    CHECK_NOT_NULL(isolate_);
75
134k
    isolate_->Enter();
76
134k
  };
77
78
134k
  void Teardown() {
79
134k
    platform->DrainTasks(isolate_);
80
134k
    isolate_->Exit();
81
134k
    platform->UnregisterIsolate(isolate_);
82
134k
    isolate_->Dispose();
83
134k
    isolate_ = nullptr;
84
134k
  }
85
};
86
87
10.2k
void EnvTest(v8::Isolate* isolate_, char* env_string, size_t len) {
88
10.2k
  const v8::HandleScope handle_scope(isolate_);
89
10.2k
  Argv argv;
90
91
10.2k
  node::EnvironmentFlags::Flags flags = node::EnvironmentFlags::kDefaultFlags;
92
10.2k
  auto isolate = handle_scope.GetIsolate();
93
10.2k
  v8::Local<v8::Context> context_ = node::NewContext(isolate);
94
10.2k
  context_->Enter();
95
96
10.2k
  node::IsolateData* isolate_data_ = node::CreateIsolateData(isolate, &current_loop,
97
10.2k
                                                             platform.get());
98
10.2k
  std::vector<std::string> args(*argv, *argv + 1);
99
10.2k
  std::vector<std::string> exec_args(*argv, *argv + 1);
100
10.2k
  node::Environment* environment_ = node::CreateEnvironment(isolate_data_,
101
10.2k
                                          context_, args, exec_args, flags);
102
10.2k
  node::Environment* envi = environment_;
103
10.2k
  SetProcessExitHandler(envi, [&](node::Environment* env_, int exit_code) {
104
0
    node::Stop(envi);
105
0
  });
106
10.2k
  node::LoadEnvironment(envi, "");
107
10.2k
  unsigned char* p = reinterpret_cast<unsigned char*>(env_string);
108
10.2k
  int type = node::cares_wrap::ns_t_cname_or_a;
109
110
10.2k
  v8::Local<v8::Array> srv_records = Array::New(envi->isolate());
111
10.2k
  int status = node::cares_wrap::FuzzParseGeneralReply(envi, p, (int)len, &type, srv_records);
112
  
113
  // Cleanup!
114
10.2k
  node::FreeEnvironment(environment_);
115
10.2k
  node::FreeIsolateData(isolate_data_);
116
10.2k
  context_->Exit();
117
10.2k
}
118
119
36.0k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data2, size_t size) {
120
36.0k
  FuzzerFixtureHelper ffh;
121
36.0k
  std::string s(reinterpret_cast<const char*>(data2), size);
122
36.0k
  EnvTest(ffh.isolate_, (char*)s.c_str(), size);
123
36.0k
  ffh.Teardown();
124
36.0k
  return 0;
125
36.0k
}
126