Coverage Report

Created: 2025-12-31 07:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/kea-fuzzer/fuzz_hook_flex_id4.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/dhcp4.h>
11
#include <dhcp/pkt4.h>
12
#include <dhcp/libdhcp++.h>
13
#include <dhcp4/ctrl_dhcp4_srv.h>
14
#include <dhcpsrv/callout_handle_store.h>
15
#include <log/logger_support.h>
16
#include <util/filesystem.h>
17
18
#include <cstddef>
19
#include <cstdint>
20
#include <vector>
21
#include <list>
22
#include <memory>
23
#include <iostream>
24
#include <filesystem>
25
#include <fstream>
26
#include <string>
27
#include <cstdio>
28
29
#include "helper_func.h"
30
31
using namespace isc::dhcp;
32
using namespace isc::hooks;
33
using namespace isc::util;
34
35
extern "C" int pkt4_receive(CalloutHandle& handle);
36
37
6.42k
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
38
6.42k
    if (size < 236) {
39
        // package size requires at least 236 bytes
40
30
        return 0;
41
30
    }
42
43
    // Initialise logging
44
6.39k
    setenv("KEA_LOGGER_DESTINATION", "/dev/null", 0);
45
6.39k
    setenv("KEA_LOCKFILE_DIR", "/tmp", 0);
46
6.39k
    setenv("KEA_PIDFILE_DIR", "/tmp", 0);
47
6.39k
    setenv("KEA_LFC_EXECUTABLE", "/bin/true", 0);
48
6.39k
    try {
49
6.39k
        isc::log::initLogger("fuzzer");
50
6.39k
        isc::process::Daemon::loggerInit("fuzzer", false);
51
6.39k
        isc::process::Daemon::setDefaultLoggerName("fuzzer");
52
6.39k
    } catch (...) {
53
        // Early exit if logging initialisation failed
54
0
        return 0;
55
0
    }
56
57
6.39k
    Pkt4Ptr pkt;
58
59
    // Package parsing
60
6.39k
    try {
61
        // Add fixed magic cookie and correct hardware address
62
6.39k
        std::vector<uint8_t> buf(data, data + size);
63
6.39k
        if (size >= 240) {
64
            // Max hardware address length is 20
65
6.32k
            buf[2] = 20;
66
67
            // Magic cookie fixed value 0x63825363
68
6.32k
            buf[236] = 0x63;
69
6.32k
            buf[237] = 0x82;
70
6.32k
            buf[238] = 0x53;
71
6.32k
            buf[239] = 0x63;
72
6.32k
        }
73
74
6.39k
        pkt = Pkt4Ptr(new Pkt4(buf.data(), buf.size()));
75
6.39k
        pkt->unpack();
76
6.39k
    } catch (...) {
77
        // Early exit if package parsing failed.
78
3.03k
        return 0;
79
3.03k
    }
80
81
    // Configure random value in packet
82
3.35k
    FuzzedDataProvider fdp(data, size);
83
3.35k
    uint8_t typeChoice = fdp.ConsumeIntegralInRange<uint8_t>(0, 8);
84
3.35k
    pkt->setType(static_cast<DHCPMessageType>(typeChoice));
85
86
3.35k
    CalloutHandlePtr handle = getCalloutHandle(pkt);
87
88
    // Fuzz pkt4_receive
89
3.35k
    try {
90
3.35k
        handle->setArgument("query4", pkt);
91
3.35k
        pkt4_receive(*handle);
92
3.35k
    } catch (const isc::Exception& e) {
93
        // Slient exceptions
94
0
    } catch (const boost::exception& e) {
95
        // Slient exceptions
96
0
    }
97
98
    // Clean handle to avoid mem leak
99
3.35k
    if (handle) {
100
3.35k
        handle->deleteAllArguments();
101
3.35k
    }
102
103
3.35k
    return 0;
104
3.35k
}