Coverage Report

Created: 2026-03-31 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kea-fuzzer/fuzz_pgsql6.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 <dhcp/pgsql/pgsql_cb_impl.h>
14
#include <dhcp/pgsql/pgsql_cb_dhcp6.h>
15
#include <dhcpsrv/subnet.h>
16
#include <dhcpsrv/host.h>
17
#include <pgsql/pgsql_exchange.h>
18
19
#include <log/logger_support.h>
20
#include <process/daemon.h>
21
#include <exceptions/exceptions.h>
22
23
#include <cstdint>
24
#include <cstddef>
25
#include <string>
26
#include <vector>
27
#include <map>
28
#include <utility>
29
#include <iostream>
30
31
using namespace isc::asiolink;
32
using namespace isc::db;
33
using namespace isc::dhcp;
34
using namespace isc::util;
35
36
extern "C" void pgmock_load_bytes(const uint8_t* data, size_t size);
37
38
6.10k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
39
    // Initialise logging
40
6.10k
    setenv("KEA_LOGGER_DESTINATION", "/dev/null", 0);
41
6.10k
    setenv("KEA_LOCKFILE_DIR", "/tmp", 0);
42
6.10k
    setenv("KEA_PIDFILE_DIR", "/tmp", 0);
43
6.10k
    setenv("KEA_LFC_EXECUTABLE", "/bin/true", 0);
44
6.10k
    try {
45
6.10k
        isc::log::initLogger("fuzzer");
46
6.10k
        isc::process::Daemon::loggerInit("fuzzer", false);
47
6.10k
        isc::process::Daemon::setDefaultLoggerName("fuzzer");
48
6.10k
    } catch (...) {
49
        // Early exit if logging initialisation failed
50
0
        return 0;
51
0
    }
52
53
6.10k
    FuzzedDataProvider fdp(data, size);
54
6.10k
    pgmock_load_bytes(data, size);
55
56
6.10k
    DbCallback db_cb;
57
6.10k
    size_t index = 0;
58
59
    // Prepare tags
60
6.10k
    std::set<std::string> tags;
61
6.10k
    std::string tag = fdp.ConsumeRandomLengthString(16);
62
6.10k
    if (tag.size() == 0) {
63
5.37k
        tag = "default-tag";
64
5.37k
    }
65
6.10k
    tags.insert(tag);
66
67
    // Preparer DatabaseConnection parameter map
68
6.10k
    DatabaseConnection::ParameterMap params;
69
6.10k
    params[fdp.ConsumeRandomLengthString(32)] = fdp.ConsumeRandomLengthString(32);
70
6.10k
    params[fdp.ConsumeRandomLengthString(32)] = fdp.ConsumeRandomLengthString(32);
71
6.10k
    params[fdp.ConsumeRandomLengthString(32)] = fdp.ConsumeRandomLengthString(32);
72
73
    // Prepare Binding array
74
6.10k
    PsqlBindArray binds;
75
6.10k
    binds.add(fdp.ConsumeRandomLengthString(256));
76
6.10k
    binds.add(fdp.ConsumeRandomLengthString(256));
77
6.10k
    binds.add(fdp.ConsumeRandomLengthString(256));
78
79
    // Prepare server selector
80
6.10k
    ServerSelector selector = ServerSelector::UNASSIGNED();
81
6.10k
    try {
82
6.10k
        switch (fdp.ConsumeIntegralInRange<int>(0, 3)) {
83
5.37k
            case 0:
84
5.37k
                selector = ServerSelector::ALL();
85
5.37k
                break;
86
222
            case 1:
87
222
                selector = ServerSelector::ONE(tag);
88
222
                break;
89
371
            case 2:
90
371
                selector = ServerSelector::MULTIPLE(tags);
91
371
                break;
92
132
            case 3:
93
132
                selector = ServerSelector::ANY();
94
132
                break;
95
6.10k
        }
96
6.10k
    } catch (const isc::Exception&) {
97
        // Slient exceptions use default unassigned server selector
98
24
    }
99
100
6.10k
    try {
101
        // Prepare PgSql backend
102
6.10k
        PgSqlConfigBackendImpl backend(fdp.ConsumeRandomLengthString(32), params, db_cb, index);
103
6.10k
        PgSqlConfigBackendDHCPv6 dhcp_backend(params);
104
105
        // Target selectQuery
106
6.10k
        try {
107
6.10k
            backend.selectQuery(0, binds, PgSqlConnection::ConsumeResultRowFun([](PgSqlResult&, int) {}));
108
6.10k
        } catch (const isc::Exception&) {
109
            // Slient exceptions
110
0
        }
111
112
        // Target insertQuery
113
6.10k
        try {
114
0
            backend.insertQuery(0, binds);
115
0
        } catch (const isc::Exception&) {
116
            // Slient exceptions
117
0
        }
118
119
        // Target updateDeleteQuery
120
0
        try {
121
0
            backend.updateDeleteQuery(0, binds);
122
0
        } catch (const isc::Exception&) {
123
            // Slient exceptions
124
0
        }
125
126
        // Target upper level getGlobalParameter6
127
0
        try {
128
0
            dhcp_backend.getGlobalParameter6(selector, fdp.ConsumeRandomLengthString(32));
129
0
        } catch (const isc::Exception&) {
130
            // Slient exceptions
131
0
        }
132
133
        // Target upper level getAllSubnets6
134
0
        try {
135
0
            dhcp_backend.getAllSubnets6(selector);
136
0
        } catch (const isc::Exception&) {
137
            // Slient exceptions
138
0
        }
139
140
        // Target upper level createUpdateSubnet6
141
0
        try {
142
0
            IOAddress address(fdp.ConsumeRandomLengthString(64));
143
0
            uint32_t a1 = fdp.ConsumeIntegral<uint32_t>();
144
0
            uint32_t b1 = fdp.ConsumeIntegral<uint32_t>();
145
0
            uint32_t c1 = fdp.ConsumeIntegral<uint32_t>();
146
0
            Triplet<uint32_t> t1(a1, b1, c1);
147
148
0
            uint32_t a2 = fdp.ConsumeIntegral<uint32_t>();
149
0
            uint32_t b2 = fdp.ConsumeIntegral<uint32_t>();
150
0
            uint32_t c2 = fdp.ConsumeIntegral<uint32_t>();
151
0
            Triplet<uint32_t> t2(a2, b2, c2);
152
153
0
            uint32_t a3 = fdp.ConsumeIntegral<uint32_t>();
154
0
            uint32_t b3 = fdp.ConsumeIntegral<uint32_t>();
155
0
            uint32_t c3 = fdp.ConsumeIntegral<uint32_t>();
156
0
            Triplet<uint32_t> t3(a3, b3, c3);
157
158
0
            uint32_t a4 = fdp.ConsumeIntegral<uint32_t>();
159
0
            uint32_t b4 = fdp.ConsumeIntegral<uint32_t>();
160
0
            uint32_t c4 = fdp.ConsumeIntegral<uint32_t>();
161
0
            Triplet<uint32_t> t4(a4, b4, c4);
162
163
0
            SubnetID sid = static_cast<SubnetID>(fdp.ConsumeIntegral<uint32_t>());
164
165
0
            Subnet6Ptr subnet(Subnet6::create(address, fdp.ConsumeIntegralInRange(0, 128), t1, t2, t3, t4, sid));
166
0
            dhcp_backend.createUpdateSubnet6(selector, subnet);
167
0
        } catch (const isc::Exception&) {
168
            // Slient exceptions
169
0
        }
170
171
        // Target upper level deleteSubnet6
172
0
        try {
173
0
            dhcp_backend.deleteSubnet6(selector, fdp.ConsumeRandomLengthString(32));
174
0
        } catch (const isc::Exception&) {
175
            // Slient exceptions
176
0
        }
177
178
        // Target upper level createUpdateOption6
179
0
        try {
180
0
            OptionBuffer opt_buf;
181
0
            OptionPtr opt(new Option(Option::V6, 0, opt_buf));
182
0
            OptionDescriptorPtr opt_desc(new OptionDescriptor(opt, true, true));
183
184
0
            std::string opt_space = "dhcp4";
185
0
            std::string opt_name  = fdp.ConsumeRandomLengthString(32);
186
0
            if (opt_name.empty()) {
187
0
                opt_name = "fuzz-opt";
188
0
            }
189
190
0
            dhcp_backend.createUpdateOption6(selector, opt_name, opt_desc);
191
0
        } catch (const isc::Exception&) {
192
            // Slient exceptions
193
0
        }
194
6.10k
    } catch (const isc::Exception&) {
195
        // Slient exceptions
196
6.10k
    }
197
198
6.10k
    return 0;
199
6.10k
}