Coverage Report

Created: 2025-11-16 07:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kea-fuzzer/fuzz_dhcp_pkt6.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 <dhcp/pkt6.h>
11
#include <dhcp/libdhcp++.h>
12
#include <dhcp/option.h>
13
#include <dhcp6/ctrl_dhcp6_srv.h>
14
#include <dhcp/option_vendor_class.h>
15
#include <log/logger_support.h>
16
#include <process/daemon.h>
17
#include <util/filesystem.h>
18
19
#include <cstddef>
20
#include <cstdint>
21
#include <vector>
22
#include <list>
23
#include <memory>
24
#include <iostream>
25
#include <filesystem>
26
#include <fstream>
27
#include <string>
28
#include <cstdio>
29
30
#include "helper_func.h"
31
32
using namespace isc::dhcp;
33
using namespace isc::hooks;
34
35
static thread_local FuzzedDataProvider* fdp = nullptr;
36
37
2.49k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
38
2.49k
    if (size < 236) {
39
        // package size requires at least 236 bytes
40
15
        return 0;
41
15
    }
42
43
    // Randomly enable validatePath checking
44
2.47k
    fdp = new FuzzedDataProvider(data, size);
45
2.47k
    isc::util::file::PathChecker::enableEnforcement(fdp->ConsumeBool());
46
47
    // Initialise logging
48
2.47k
    setenv("KEA_LOGGER_DESTINATION", "/dev/null", 0);
49
2.47k
    setenv("KEA_LOCKFILE_DIR", "/tmp", 0);
50
2.47k
    setenv("KEA_PIDFILE_DIR", "/tmp", 0);
51
2.47k
    setenv("KEA_LFC_EXECUTABLE", "/bin/true", 0);
52
2.47k
    try {
53
2.47k
        isc::log::initLogger("fuzzer");
54
2.47k
        isc::process::Daemon::loggerInit("fuzzer", false);
55
2.47k
        isc::process::Daemon::setDefaultLoggerName("fuzzer");
56
2.47k
    } catch (...) {
57
        // Early exit if logging initialisation failed
58
0
        return 0;
59
0
    }
60
61
    // Create temporary configuration file
62
2.47k
    std::string path = fuzz::writeTempConfig(true);
63
2.47k
    if (path.empty()) {
64
        // Early exit if configuration file creation failed
65
0
        fuzz::deleteTempFile(path);
66
0
        return 0;
67
0
    }
68
69
2.47k
    OptionCollection options;
70
2.47k
    std::unique_ptr<ControlledDhcpv6Srv> srv;
71
2.47k
    std::vector<uint8_t> buf(data, data + size);
72
73
2.47k
    try {
74
2.47k
        Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(data, size));
75
2.47k
        pkt->toText();
76
2.47k
        pkt->getType();
77
2.47k
        pkt->getTransid();
78
2.47k
        pkt->unpack();
79
2.47k
        pkt->pack();
80
2.47k
        pkt->getMAC(fdp->ConsumeIntegral<uint32_t>());
81
2.47k
        pkt->getName(fdp->ConsumeIntegral<uint8_t>());
82
2.47k
        pkt->getLabel();
83
2.47k
    } catch (...) {}
84
85
    // OptionVendor parsing
86
2.47k
    try {
87
2.47k
        OptionBuffer buf(data, data + size);
88
2.47k
        OptionVendorClassPtr vendor_class;
89
2.47k
        vendor_class = OptionVendorClassPtr(new OptionVendorClass(Option::V6,
90
2.47k
            buf.begin(),
91
2.47k
            buf.end()));
92
2.47k
    }catch(...){}
93
94
2.47k
    try {
95
        // Package parsing
96
2.47k
        Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(data, size));
97
2.47k
        pkt->toText();
98
2.47k
        pkt->getType();
99
2.47k
        pkt->getTransid();
100
101
        // Option parsing
102
2.47k
        LibDHCP::unpackOptions6(buf, DHCP6_OPTION_SPACE, options);
103
175k
        for (auto& kv : options) {
104
175k
            auto opt = kv.second;
105
175k
            if (!opt) {
106
0
                continue;
107
0
            }
108
175k
            opt->getType();
109
175k
            opt->toText();
110
175k
        }
111
112
        // Server initialisation
113
2.47k
        srv.reset(new ControlledDhcpv6Srv());
114
2.47k
        srv->init(path);
115
116
        // Process packet
117
2.47k
        if (srv) {
118
0
            srv->processPacket(pkt);
119
0
            srv->processDhcp6Query(pkt);
120
0
        }
121
2.47k
    } catch (const isc::Exception& e) {
122
        // Slient exceptions
123
2.47k
    }
124
125
2.47k
    srv.reset();
126
127
    // Remove temp configuration file
128
2.47k
    fuzz::deleteTempFile(path);
129
2.47k
    delete fdp;
130
2.47k
    return 0;
131
2.47k
}