/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 | } |