Coverage Report

Created: 2025-11-16 07:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kea-fuzzer/fuzz_mysql6.cc
Line
Count
Source
1
// Copyright (C) 2025 Ada Logcis Ltd.
2
//
3
// This Source Code Form is subject to the terms of the Mozilla Public
4
// License, v. 2.0. If a copy of the MPL was not distributed with this
5
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
////////////////////////////////////////////////////////////////////////////////
7
#include <config.h>
8
#include <fuzzer/FuzzedDataProvider.h>
9
10
#include <asiolink/io_address.h>
11
#include <database/database_connection.h>
12
#include <database/server_selector.h>
13
#include <dhcpsrv/subnet.h>
14
#include <dhcpsrv/host.h>
15
#include <dhcpsrv/cfg_option.h>
16
17
#include <log/logger_support.h>
18
#include <process/daemon.h>
19
#include <exceptions/exceptions.h>
20
21
#include <mysql_cb_impl.h>
22
#include <mysql_cb_dhcp6.h>
23
24
#include <cstdint>
25
#include <cstddef>
26
#include <string>
27
#include <set>
28
#include <vector>
29
#include <map>
30
#include <utility>
31
#include <iostream>
32
33
using namespace isc::asiolink;
34
using namespace isc::db;
35
using namespace isc::dhcp;
36
using namespace isc::util;
37
38
extern "C" void mysqlmock_load_bytes(const uint8_t* data, size_t size);
39
40
6.76k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
41
    // Initialise logging
42
6.76k
    setenv("KEA_LOGGER_DESTINATION", "/dev/null", 0);
43
6.76k
    setenv("KEA_LOCKFILE_DIR", "/tmp", 0);
44
6.76k
    setenv("KEA_PIDFILE_DIR", "/tmp", 0);
45
6.76k
    setenv("KEA_LFC_EXECUTABLE", "/bin/true", 0);
46
6.76k
    try {
47
6.76k
        isc::log::initLogger("fuzzer");
48
6.76k
        isc::process::Daemon::loggerInit("fuzzer", false);
49
6.76k
        isc::process::Daemon::setDefaultLoggerName("fuzzer");
50
6.76k
    } catch (...) {
51
        // Early exit if logging initialisation failed
52
0
        return 0;
53
0
    }
54
55
6.76k
    FuzzedDataProvider fdp(data, size);
56
6.76k
    mysqlmock_load_bytes(data, size);
57
6.76k
    DbCallback db_cb;
58
59
    // Prepare tags
60
6.76k
    std::set<std::string> tags;
61
6.76k
    std::string tag = fdp.ConsumeRandomLengthString(16);
62
6.76k
    if (tag.empty()) {
63
2.46k
        tag = "default-tag";
64
2.46k
    }
65
6.76k
    tags.insert(tag);
66
67
    // Prepare DatabaseConnection parameter maps
68
6.76k
    DatabaseConnection::ParameterMap params;
69
6.76k
    std::string dbname = fdp.ConsumeRandomLengthString(16);
70
6.76k
    if (dbname.empty()) {
71
3.35k
        dbname = "kea_fuzz";
72
3.35k
    }
73
6.76k
    params["name"] = dbname;
74
6.76k
    params[fdp.ConsumeRandomLengthString(16)] = fdp.ConsumeRandomLengthString(16);
75
6.76k
    params[fdp.ConsumeRandomLengthString(16)] = fdp.ConsumeRandomLengthString(16);
76
77
    // Prepare server selector
78
6.76k
    ServerSelector selector = ServerSelector::UNASSIGNED();
79
6.76k
    try {
80
6.76k
        switch (fdp.ConsumeIntegralInRange<int>(0, 3)) {
81
4.87k
            case 0: selector = ServerSelector::ALL(); break;
82
974
            case 1: selector = ServerSelector::ONE(tag); break;
83
515
            case 2: selector = ServerSelector::MULTIPLE(tags); break;
84
395
            case 3: selector = ServerSelector::ANY(); break;
85
6.76k
        }
86
6.76k
    } catch (const isc::Exception&) {
87
        // Silent exceptions use default UNASSIGNED
88
79
    }
89
90
6.76k
    try {
91
6.76k
        MySqlConfigBackendImpl backend("v6", params, db_cb);
92
6.76k
        MySqlConfigBackendDHCPv6 dhcp_backend(params);
93
94
        // Target getGlobalParameter6
95
6.76k
        try {
96
6.76k
            dhcp_backend.getGlobalParameter6(selector, fdp.ConsumeRandomLengthString(32));
97
6.76k
        } catch (const isc::Exception& e) {
98
            // Slient exceptions
99
2.59k
        }
100
101
        // Target getAllSubnets6
102
6.76k
        try {
103
6.45k
            dhcp_backend.getAllSubnets6(selector);
104
6.45k
        } catch (const isc::Exception& e) {
105
            // Slient exceptions
106
1.12k
        }
107
108
        // Target createUpdateSubnet6
109
6.45k
        try {
110
6.45k
            IOAddress address("::1");
111
112
6.45k
            uint32_t a1 = fdp.ConsumeIntegral<uint32_t>();
113
6.45k
            uint32_t b1 = fdp.ConsumeIntegral<uint32_t>();
114
6.45k
            uint32_t c1 = fdp.ConsumeIntegral<uint32_t>();
115
6.45k
            Triplet<uint32_t> t1(a1, b1, c1);
116
117
6.45k
            uint32_t a2 = fdp.ConsumeIntegral<uint32_t>();
118
6.45k
            uint32_t b2 = fdp.ConsumeIntegral<uint32_t>();
119
6.45k
            uint32_t c2 = fdp.ConsumeIntegral<uint32_t>();
120
6.45k
            Triplet<uint32_t> t2(a2, b2, c2);
121
122
6.45k
            uint32_t a3 = fdp.ConsumeIntegral<uint32_t>();
123
6.45k
            uint32_t b3 = fdp.ConsumeIntegral<uint32_t>();
124
6.45k
            uint32_t c3 = fdp.ConsumeIntegral<uint32_t>();
125
6.45k
            Triplet<uint32_t> t3(a3, b3, c3);
126
127
6.45k
            uint32_t a4 = fdp.ConsumeIntegral<uint32_t>();
128
6.45k
            uint32_t b4 = fdp.ConsumeIntegral<uint32_t>();
129
6.45k
            uint32_t c4 = fdp.ConsumeIntegral<uint32_t>();
130
6.45k
            Triplet<uint32_t> t4(a4, b4, c4);
131
132
6.45k
            SubnetID sid = static_cast<SubnetID>(fdp.ConsumeIntegralInRange<uint32_t>(1, UINT32_MAX));
133
6.45k
            Subnet6Ptr subnet(Subnet6::create(address,
134
6.45k
                                              fdp.ConsumeIntegralInRange(0, 32),
135
6.45k
                                              t1, t2, t3, t4, sid));
136
6.45k
            dhcp_backend.createUpdateSubnet6(selector, subnet);
137
6.45k
        } catch (const isc::Exception& e) {
138
            // Slient exceptions
139
2.00k
        }
140
141
        // Target deleteSubnet6
142
6.45k
        try {
143
6.45k
            dhcp_backend.deleteSubnet6(selector, fdp.ConsumeRandomLengthString(32));
144
6.45k
        } catch (const isc::Exception& e) {
145
            // Slient exceptions
146
73
        }
147
148
        // Target createUpdateOption6
149
6.45k
        try {
150
6.45k
            OptionBuffer opt_buf;
151
6.45k
            OptionPtr opt(new Option(Option::V4, fdp.ConsumeIntegralInRange<uint16_t>(1, 254), opt_buf));
152
6.45k
            OptionDescriptorPtr opt_desc(new OptionDescriptor(opt, true, true));
153
154
6.45k
            std::string opt_space = "dhcp4";
155
6.45k
            std::string opt_name  = fdp.ConsumeRandomLengthString(32);
156
6.45k
            if (opt_name.empty()) {
157
5.12k
                opt_name = "fuzz-opt";
158
5.12k
            }
159
160
6.45k
            dhcp_backend.createUpdateOption6(selector, opt_name, opt_desc);
161
6.45k
        } catch (const isc::Exception& e) {
162
            // Slient exceptions
163
73
        }
164
6.45k
    } catch (const isc::Exception&) {
165
        // Silent top-level exceptions
166
307
    }
167
168
6.76k
    return 0;
169
6.76k
}