Coverage Report

Created: 2026-02-26 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/fuzz_daemon_connection.cpp
Line
Count
Source
1
// Copyright 2025 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
//
15
////////////////////////////////////////////////////////////////////////////////
16
#include <stdint.h>
17
#include <stddef.h>
18
#include <string>
19
#include <vector>
20
#include <cstring>
21
22
#include "fuzzer/FuzzedDataProvider.h"
23
#include "connection_helper.h"
24
25
#include "conn_tls_check.h"
26
#include "mempool_funcs.h"
27
#include "mhd_send.h"
28
#include "stream_process_request.h"
29
#include "stream_process_states.h"
30
31
32
// Initialising the memory pool
33
2
extern "C" int LLVMFuzzerInitialize() {
34
2
  g_pool = mhd_pool_create(g_pool_size, MHD_MEMPOOL_ZEROING_ON_RESET);
35
2
  atexit(destroy_global_pool);
36
2
  return 0;
37
2
}
38
39
5
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
40
5
  if (size == 0 || g_pool == nullptr) {
41
0
    return 0;
42
0
  }
43
44
5
  FuzzedDataProvider fdp(data, size);
45
46
  // Reseting the memory pool for each iteartion
47
5
  mhd_pool_destroy(g_pool);
48
5
  g_pool = mhd_pool_create(g_pool_size, MHD_MEMPOOL_ZEROING_ON_RESET);
49
50
  // Initialising the daemon, connection and other MHD components
51
5
  MHD_Daemon daemon;
52
5
  MHD_Connection connection;
53
5
  init_daemon_connection(fdp, daemon, connection);
54
5
  init_parsing_configuration(fdp, connection);
55
5
  init_connection_buffer(fdp, connection);
56
5
  prepare_headers_and_parse(connection, size);
57
58
  // Randomly choose how many targets to fuzz
59
5
  std::vector<int> selectors;
60
15
  for (int i = 0; i < fdp.ConsumeIntegralInRange<int>(1, 8); i++) {
61
10
    selectors.push_back(fdp.ConsumeIntegralInRange<int>(0, 5));
62
10
  }
63
64
  // Generate random flags
65
5
  bool use_stream_body = fdp.ConsumeBool();
66
5
  bool is_nodelay = fdp.ConsumeBool();
67
5
  bool is_cork = fdp.ConsumeBool();
68
69
  // Use remaining bytes to generate random body for fuzzing
70
5
  std::string body = fdp.ConsumeRemainingBytesAsString();
71
5
  size_t body_size = body.size();
72
5
  if (body_size == 0) {
73
0
    return 0;
74
0
  }
75
5
  prepare_body_and_process(connection, body, body_size, use_stream_body);
76
77
10
  for (int selector : selectors) {
78
10
    switch (selector) {
79
2
      case 0: {
80
2
        mhd_conn_event_loop_state_update(&connection);
81
2
        break;
82
0
      }
83
1
      case 1: {
84
1
        if (connection.rq.app_act.head_act.act == mhd_ACTION_NO_ACTION &&
85
0
            connection.daemon && connection.daemon->req_cfg.cb) {
86
0
          mhd_stream_call_app_request_cb(&connection);
87
0
        }
88
1
        break;
89
0
      }
90
2
      case 2: {
91
2
        if (connection.rq.app_act.head_act.act == mhd_ACTION_POST_PARSE &&
92
0
            connection.rq.app_act.head_act.data.post_parse.done_cb != nullptr &&
93
0
            is_post_parse_ready(connection)) {
94
0
          mhd_stream_process_req_recv_finished(&connection);
95
0
        }
96
2
        break;
97
0
      }
98
5
      default: case 3: {
99
5
        mhd_conn_tls_check(&connection);
100
5
        break;
101
5
      }
102
10
    }
103
10
  }
104
105
5
  final_cleanup(connection, daemon);
106
5
  return 0;
107
5
}