Coverage Report

Created: 2025-11-09 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openthread/tests/fuzz/fuzz_cli.cpp
Line
Count
Source
1
/*
2
 *  Copyright (c) 2025, The OpenThread Authors.
3
 *  All rights reserved.
4
 *
5
 *  Redistribution and use in source and binary forms, with or without
6
 *  modification, are permitted provided that the following conditions are met:
7
 *  1. Redistributions of source code must retain the above copyright
8
 *     notice, this list of conditions and the following disclaimer.
9
 *  2. Redistributions in binary form must reproduce the above copyright
10
 *     notice, this list of conditions and the following disclaimer in the
11
 *     documentation and/or other materials provided with the distribution.
12
 *  3. Neither the name of the copyright holder nor the
13
 *     names of its contributors may be used to endorse or promote products
14
 *     derived from this software without specific prior written permission.
15
 *
16
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26
 *  POSSIBILITY OF SUCH DAMAGE.
27
 */
28
29
#include <stdarg.h>
30
#include <stdio.h>
31
#include <stdlib.h>
32
#include <string.h>
33
34
#include <openthread/cli.h>
35
36
#include "platform/nexus_core.hpp"
37
#include "platform/nexus_node.hpp"
38
39
namespace ot {
40
namespace Nexus {
41
42
class FuzzDataProvider
43
{
44
public:
45
    FuzzDataProvider(const uint8_t *aData, size_t aSize)
46
21.7k
        : mData(aData)
47
21.7k
        , mSize(aSize)
48
21.7k
    {
49
21.7k
    }
50
51
    void ConsumeData(void *aBuf, size_t aLength)
52
50.4k
    {
53
50.4k
        assert(aLength <= mSize);
54
50.4k
        memcpy(aBuf, mData, aLength);
55
50.4k
        mData += aLength;
56
50.4k
        mSize -= aLength;
57
50.4k
    }
58
59
    uint8_t *ConsumeRemainingBytes(void)
60
16.3k
    {
61
16.3k
        uint8_t *buf = static_cast<uint8_t *>(malloc(mSize + 1));
62
16.3k
        memcpy(buf, mData, mSize);
63
16.3k
        buf[mSize] = '\0';
64
16.3k
        mSize      = 0;
65
16.3k
        return buf;
66
16.3k
    }
67
68
    size_t RemainingBytes(void) { return mSize; }
69
70
private:
71
    const uint8_t *mData;
72
    size_t         mSize;
73
};
74
75
static int CliOutput(void *aContext, const char *aFormat, va_list aArguments)
76
87.5k
{
77
87.5k
    OT_UNUSED_VARIABLE(aContext);
78
87.5k
    OT_UNUSED_VARIABLE(aFormat);
79
87.5k
    OT_UNUSED_VARIABLE(aArguments);
80
81
87.5k
    return vsnprintf(nullptr, 0, aFormat, aArguments);
82
87.5k
}
83
84
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
85
8.92k
{
86
8.92k
    const uint16_t kMaxCommandSize = 4096;
87
88
8.92k
    FuzzDataProvider fdp(data, size);
89
90
8.92k
    unsigned int seed;
91
8.92k
    uint8_t     *buffer;
92
93
8.92k
    if (size < sizeof(seed))
94
11
    {
95
11
        return 0;
96
11
    }
97
98
8.91k
    if (size > kMaxCommandSize)
99
21
    {
100
21
        return 0;
101
21
    }
102
103
8.89k
    fdp.ConsumeData(&seed, sizeof(seed));
104
8.89k
    srand(seed);
105
106
8.89k
    Core nexus;
107
108
8.89k
    Node &node = nexus.CreateNode();
109
110
8.89k
    node.GetInstance().SetLogLevel(kLogLevelInfo);
111
112
8.89k
    otCliInit(&node.GetInstance(), CliOutput, nullptr);
113
114
8.89k
    node.GetInstance().Get<BorderRouter::InfraIf>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
115
8.89k
    node.GetInstance().Get<BorderRouter::RoutingManager>().SetEnabled(true);
116
8.89k
    node.GetInstance().Get<Srp::Server>().SetAutoEnableMode(true);
117
8.89k
    node.GetInstance().Get<BorderRouter::RoutingManager>().SetDhcp6PdEnabled(true);
118
8.89k
    node.GetInstance().Get<BorderRouter::RoutingManager>().SetNat64PrefixManagerEnabled(true);
119
8.89k
    node.GetInstance().Get<Nat64::Translator>().SetEnabled(true);
120
121
8.89k
    Log("---------------------------------------------------------------------------------------");
122
8.89k
    Log("Form network");
123
124
8.89k
    node.Form();
125
8.89k
    nexus.AdvanceTime(60 * 1000);
126
8.89k
    VerifyOrQuit(node.Get<Mle::Mle>().IsLeader());
127
8.89k
    VerifyOrQuit(node.Get<Srp::Server>().GetState() == Srp::Server::kStateRunning);
128
129
8.89k
    Log("---------------------------------------------------------------------------------------");
130
8.89k
    Log("Fuzz");
131
132
8.89k
    buffer = fdp.ConsumeRemainingBytes();
133
134
8.89k
    otCliInputLine(reinterpret_cast<char *>(buffer));
135
136
8.89k
    nexus.AdvanceTime(60 * 1000);
137
138
8.89k
    free(buffer);
139
140
8.89k
    return 0;
141
8.89k
}
142
143
} // namespace Nexus
144
} // namespace ot