Coverage Report

Created: 2025-07-23 06:29

/src/openthread/tests/fuzz/radio-one-node.cpp
Line
Count
Source (jump to first uncovered line)
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 "platform/nexus_core.hpp"
35
#include "platform/nexus_node.hpp"
36
37
namespace ot {
38
namespace Nexus {
39
40
class FuzzDataProvider
41
{
42
public:
43
    FuzzDataProvider(const uint8_t *aData, size_t aSize)
44
6.66k
        : mData(aData)
45
6.66k
        , mSize(aSize)
46
6.66k
    {
47
6.66k
    }
48
49
    void ConsumeData(void *aBuf, size_t aLength)
50
19.9k
    {
51
19.9k
        assert(aLength <= mSize);
52
19.9k
        memcpy(aBuf, mData, aLength);
53
19.9k
        mData += aLength;
54
19.9k
        mSize -= aLength;
55
19.9k
    }
56
57
    uint8_t *ConsumeRemainingBytes(void)
58
6.64k
    {
59
6.64k
        uint8_t *buf = static_cast<uint8_t *>(malloc(mSize));
60
6.64k
        memcpy(buf, mData, mSize);
61
6.64k
        mSize = 0;
62
6.64k
        return buf;
63
6.64k
    }
64
65
    uint8_t ConsumeIntegralInRange(uint8_t aMin, uint8_t aMax)
66
6.64k
    {
67
6.64k
        assert(aMin < aMax);
68
69
6.64k
        uint16_t range = aMax - aMin;
70
6.64k
        uint8_t  result;
71
72
6.64k
        ConsumeData(&result, sizeof(result));
73
74
6.64k
        result = result % (range + 1);
75
76
6.64k
        return result + aMin;
77
6.64k
    }
78
79
6.64k
    size_t RemainingBytes(void) { return mSize; }
80
81
private:
82
    const uint8_t *mData;
83
    size_t         mSize;
84
};
85
86
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
87
6.66k
{
88
6.66k
    FuzzDataProvider fdp(data, size);
89
90
6.66k
    unsigned int seed;
91
6.66k
    otRadioFrame frame;
92
6.66k
    otError      error;
93
94
6.66k
    if (size < sizeof(seed) + sizeof(error) + sizeof(frame))
95
10
    {
96
10
        return 0;
97
10
    }
98
99
6.65k
    if (size > sizeof(seed) + sizeof(error) + sizeof(frame) + OT_RADIO_FRAME_MAX_SIZE)
100
16
    {
101
16
        return 0;
102
16
    }
103
104
6.64k
    fdp.ConsumeData(&seed, sizeof(seed));
105
6.64k
    srand(seed);
106
107
6.64k
    Core nexus;
108
109
6.64k
    Node &node = nexus.CreateNode();
110
111
6.64k
    node.GetInstance().SetLogLevel(kLogLevelInfo);
112
113
6.64k
    node.GetInstance().Get<BorderRouter::RoutingManager>().Init(/* aInfraIfIndex */ 1, /* aInfraIfIsRunning */ true);
114
6.64k
    node.GetInstance().Get<BorderRouter::RoutingManager>().SetEnabled(true);
115
6.64k
    node.GetInstance().Get<Srp::Server>().SetAutoEnableMode(true);
116
6.64k
    node.GetInstance().Get<BorderRouter::RoutingManager>().SetDhcp6PdEnabled(true);
117
6.64k
    node.GetInstance().Get<BorderRouter::RoutingManager>().SetNat64PrefixManagerEnabled(true);
118
6.64k
    node.GetInstance().Get<Nat64::Translator>().SetEnabled(true);
119
120
6.64k
    Log("---------------------------------------------------------------------------------------");
121
6.64k
    Log("Form network");
122
123
6.64k
    node.Form();
124
6.64k
    nexus.AdvanceTime(60 * 1000);
125
6.64k
    VerifyOrQuit(node.Get<Mle::Mle>().IsLeader());
126
6.64k
    VerifyOrQuit(node.Get<Srp::Server>().GetState() == Srp::Server::kStateRunning);
127
128
6.64k
    Log("---------------------------------------------------------------------------------------");
129
6.64k
    Log("Fuzz");
130
131
6.64k
    error = static_cast<otError>(fdp.ConsumeIntegralInRange(OT_ERROR_NONE, OT_NUM_ERRORS - 1));
132
133
6.64k
    fdp.ConsumeData(&frame, sizeof(frame));
134
135
6.64k
    frame.mLength = fdp.RemainingBytes();
136
137
6.64k
    if (frame.mLength == 0)
138
0
    {
139
0
        frame.mPsdu = NULL;
140
0
    }
141
6.64k
    else
142
6.64k
    {
143
6.64k
        frame.mPsdu = fdp.ConsumeRemainingBytes();
144
6.64k
    }
145
146
6.64k
    otPlatRadioReceiveDone(&node.GetInstance(), &frame, error);
147
148
6.64k
    nexus.AdvanceTime(10 * 1000);
149
150
6.64k
    if (frame.mPsdu)
151
6.64k
    {
152
6.64k
        free(frame.mPsdu);
153
6.64k
    }
154
155
6.64k
exit:
156
6.64k
    return 0;
157
6.64k
}
158
159
} // namespace Nexus
160
} // namespace ot