Skip to content

Commit 4023411

Browse files
committed
add a .clang-format file
The previous setup would be extremely lenient. AFAIK would basically only enforce tabulation more or less. Add a .clang-format file, the point is you can't accidently have whitespace changes. See #9116 for what sitatuation we are in before this patch. The point is there is a single valid way to format the file, and running trunk fmt -a will bring you to it.
1 parent caceaf4 commit 4023411

771 files changed

Lines changed: 78714 additions & 84125 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.clang-format

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
BasedOnStyle: LLVM
2+
ColumnLimit: 150

.clusterfuzzlite/router_fuzzer.cpp

Lines changed: 128 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
#include "mesh/TypeConversions.h"
1717
#include "mesh/mesh-pb-constants.h"
1818

19-
namespace
20-
{
19+
namespace {
2120
constexpr uint32_t nodeId = 0x12345678;
2221
// Set to true when lateInitVariant finishes. Used to ensure lateInitVariant was called during startup.
2322
bool hasBeenConfigured = false;
@@ -35,135 +34,130 @@ std::condition_variable loopCV;
3534
std::thread meshtasticThread;
3635

3736
// This exception is thrown when the portuino main thread should exit.
38-
class ShouldExitException : public std::runtime_error
39-
{
40-
public:
41-
using std::runtime_error::runtime_error;
37+
class ShouldExitException : public std::runtime_error {
38+
public:
39+
using std::runtime_error::runtime_error;
4240
};
4341

4442
// Start the loop for one test case and wait till the loop has completed. This ensures fuzz
4543
// test cases do not overlap with one another. This helps the fuzzer attribute a crash to the
4644
// single, currently running, test case.
47-
void runLoopOnce()
48-
{
49-
realHardware = true; // Avoids delay(100) within portduino/main.cpp
50-
std::unique_lock<std::mutex> lck(loopLock);
51-
fuzzerRunning = true;
52-
loopCanRun = true;
53-
loopCV.notify_one();
54-
loopCV.wait(lck, [] { return !loopCanRun && loopIsWaiting; });
45+
void runLoopOnce() {
46+
realHardware = true; // Avoids delay(100) within portduino/main.cpp
47+
std::unique_lock<std::mutex> lck(loopLock);
48+
fuzzerRunning = true;
49+
loopCanRun = true;
50+
loopCV.notify_one();
51+
loopCV.wait(lck, [] { return !loopCanRun && loopIsWaiting; });
5552
}
5653
} // namespace
5754

5855
// Called in the main Arduino loop function to determine if the loop can delay/sleep before running again.
5956
// We use this as a way to block the loop from sleeping and to start the loop function immediately when a
6057
// fuzzer input is ready.
61-
bool loopCanSleep()
62-
{
63-
std::unique_lock<std::mutex> lck(loopLock);
64-
loopIsWaiting = true;
65-
loopCV.notify_one();
66-
loopCV.wait(lck, [] { return loopCanRun || loopShouldExit; });
67-
loopIsWaiting = false;
68-
if (loopShouldExit)
69-
throw ShouldExitException("exit");
70-
if (!fuzzerRunning)
71-
return true; // The loop can sleep before the fuzzer starts.
72-
loopCanRun = false; // Only run the loop once before waiting again.
73-
return false;
58+
bool loopCanSleep() {
59+
std::unique_lock<std::mutex> lck(loopLock);
60+
loopIsWaiting = true;
61+
loopCV.notify_one();
62+
loopCV.wait(lck, [] { return loopCanRun || loopShouldExit; });
63+
loopIsWaiting = false;
64+
if (loopShouldExit)
65+
throw ShouldExitException("exit");
66+
if (!fuzzerRunning)
67+
return true; // The loop can sleep before the fuzzer starts.
68+
loopCanRun = false; // Only run the loop once before waiting again.
69+
return false;
7470
}
7571

7672
// Called just prior to starting Meshtastic. Allows for setting config values before startup.
77-
void lateInitVariant()
78-
{
79-
portduino_config.logoutputlevel = level_error;
80-
channelFile.channels[0] = meshtastic_Channel{
81-
.has_settings = true,
82-
.settings =
83-
meshtastic_ChannelSettings{
84-
.psk = {.size = 1, .bytes = {/*defaultpskIndex=*/1}},
85-
.name = "LongFast",
86-
.uplink_enabled = true,
87-
.has_module_settings = true,
88-
.module_settings = {.position_precision = 16},
89-
},
90-
.role = meshtastic_Channel_Role_PRIMARY,
91-
};
92-
config.security.admin_key[0] = {
93-
.size = 32,
94-
.bytes = {0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, 0x0c, 0x0d, 0xec, 0x85, 0x5a,
95-
0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a, 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c},
96-
};
97-
config.security.admin_key_count = 1;
98-
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_US;
99-
moduleConfig.has_mqtt = true;
100-
moduleConfig.mqtt = meshtastic_ModuleConfig_MQTTConfig{
101-
.enabled = true,
102-
.proxy_to_client_enabled = true,
103-
};
104-
moduleConfig.has_store_forward = true;
105-
moduleConfig.store_forward = meshtastic_ModuleConfig_StoreForwardConfig{
106-
.enabled = true,
107-
.history_return_max = 4,
108-
.history_return_window = 600,
109-
.is_server = true,
110-
};
111-
meshtastic_Position fixedGPS = meshtastic_Position{
112-
.has_latitude_i = true,
113-
.latitude_i = static_cast<uint32_t>(1 * 1e7),
114-
.has_longitude_i = true,
115-
.longitude_i = static_cast<uint32_t>(3 * 1e7),
116-
.has_altitude = true,
117-
.altitude = 64,
118-
.location_source = meshtastic_Position_LocSource_LOC_MANUAL,
119-
};
120-
nodeDB->setLocalPosition(fixedGPS);
121-
config.has_position = true;
122-
config.position.fixed_position = true;
123-
meshtastic_NodeInfoLite *info = nodeDB->getMeshNode(nodeDB->getNodeNum());
124-
info->has_position = true;
125-
info->position = TypeConversions::ConvertToPositionLite(fixedGPS);
126-
hasBeenConfigured = true;
73+
void lateInitVariant() {
74+
portduino_config.logoutputlevel = level_error;
75+
channelFile.channels[0] = meshtastic_Channel{
76+
.has_settings = true,
77+
.settings =
78+
meshtastic_ChannelSettings{
79+
.psk = {.size = 1, .bytes = {/*defaultpskIndex=*/1}},
80+
.name = "LongFast",
81+
.uplink_enabled = true,
82+
.has_module_settings = true,
83+
.module_settings = {.position_precision = 16},
84+
},
85+
.role = meshtastic_Channel_Role_PRIMARY,
86+
};
87+
config.security.admin_key[0] = {
88+
.size = 32,
89+
.bytes = {0xcd, 0xc0, 0xb4, 0x3c, 0x53, 0x24, 0xdf, 0x13, 0xca, 0x5a, 0xa6, 0x0c, 0x0d, 0xec, 0x85, 0x5a,
90+
0x4c, 0xf6, 0x1a, 0x96, 0x04, 0x1a, 0x3e, 0xfc, 0xbb, 0x8e, 0x33, 0x71, 0xe5, 0xfc, 0xff, 0x3c},
91+
};
92+
config.security.admin_key_count = 1;
93+
config.lora.region = meshtastic_Config_LoRaConfig_RegionCode_US;
94+
moduleConfig.has_mqtt = true;
95+
moduleConfig.mqtt = meshtastic_ModuleConfig_MQTTConfig{
96+
.enabled = true,
97+
.proxy_to_client_enabled = true,
98+
};
99+
moduleConfig.has_store_forward = true;
100+
moduleConfig.store_forward = meshtastic_ModuleConfig_StoreForwardConfig{
101+
.enabled = true,
102+
.history_return_max = 4,
103+
.history_return_window = 600,
104+
.is_server = true,
105+
};
106+
meshtastic_Position fixedGPS = meshtastic_Position{
107+
.has_latitude_i = true,
108+
.latitude_i = static_cast<uint32_t>(1 * 1e7),
109+
.has_longitude_i = true,
110+
.longitude_i = static_cast<uint32_t>(3 * 1e7),
111+
.has_altitude = true,
112+
.altitude = 64,
113+
.location_source = meshtastic_Position_LocSource_LOC_MANUAL,
114+
};
115+
nodeDB->setLocalPosition(fixedGPS);
116+
config.has_position = true;
117+
config.position.fixed_position = true;
118+
meshtastic_NodeInfoLite *info = nodeDB->getMeshNode(nodeDB->getNodeNum());
119+
info->has_position = true;
120+
info->position = TypeConversions::ConvertToPositionLite(fixedGPS);
121+
hasBeenConfigured = true;
127122
}
128123

129124
extern "C" {
130125
int portduino_main(int argc, char **argv); // Renamed "main" function from Meshtastic binary.
131126

132127
// Start Meshtastic in a thread and wait till it has reached the ON state.
133-
int LLVMFuzzerInitialize(int *argc, char ***argv)
134-
{
135-
portduino_config.maxtophone = 5;
128+
int LLVMFuzzerInitialize(int *argc, char ***argv) {
129+
portduino_config.maxtophone = 5;
136130

137-
meshtasticThread = std::thread([program = *argv[0]]() {
138-
char nodeIdStr[12];
139-
strcpy(nodeIdStr, std::to_string(nodeId).c_str());
140-
int argc = 7;
141-
char *argv[] = {program, "-d", "/tmp/meshtastic", "-h", nodeIdStr, "-p", "0", nullptr};
142-
try {
143-
portduino_main(argc, argv);
144-
} catch (const ShouldExitException &) {
145-
}
146-
});
147-
std::atexit([] {
148-
{
149-
const std::lock_guard<std::mutex> lck(loopLock);
150-
loopShouldExit = true;
151-
loopCV.notify_one();
152-
}
153-
meshtasticThread.join();
154-
});
131+
meshtasticThread = std::thread([program = *argv[0]]() {
132+
char nodeIdStr[12];
133+
strcpy(nodeIdStr, std::to_string(nodeId).c_str());
134+
int argc = 7;
135+
char *argv[] = {program, "-d", "/tmp/meshtastic", "-h", nodeIdStr, "-p", "0", nullptr};
136+
try {
137+
portduino_main(argc, argv);
138+
} catch (const ShouldExitException &) {
139+
}
140+
});
141+
std::atexit([] {
142+
{
143+
const std::lock_guard<std::mutex> lck(loopLock);
144+
loopShouldExit = true;
145+
loopCV.notify_one();
146+
}
147+
meshtasticThread.join();
148+
});
155149

156-
// Wait for startup.
157-
for (int i = 1; i < 20; ++i) {
158-
if (powerFSM.getState() == &stateON) {
159-
assert(hasBeenConfigured);
160-
assert(router);
161-
assert(nodeDB);
162-
return 0;
163-
}
164-
std::this_thread::sleep_for(std::chrono::seconds(1));
150+
// Wait for startup.
151+
for (int i = 1; i < 20; ++i) {
152+
if (powerFSM.getState() == &stateON) {
153+
assert(hasBeenConfigured);
154+
assert(router);
155+
assert(nodeDB);
156+
return 0;
165157
}
166-
return 1;
158+
std::this_thread::sleep_for(std::chrono::seconds(1));
159+
}
160+
return 1;
167161
}
168162

169163
// This is the main entrypoint for the fuzzer (the fuzz target). The fuzzer will provide an array of bytes to be
@@ -173,34 +167,33 @@ int LLVMFuzzerInitialize(int *argc, char ***argv)
173167
//
174168
// This guide provides best practices for writing a fuzzer target.
175169
// https://github.com/google/fuzzing/blob/master/docs/good-fuzz-target.md
176-
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t length)
177-
{
178-
meshtastic_MeshPacket p = meshtastic_MeshPacket_init_default;
179-
pb_istream_t stream = pb_istream_from_buffer(data, length);
180-
// Ignore any inputs that fail to decode or have fields set that are not transmitted over LoRa.
181-
if (!pb_decode(&stream, &meshtastic_MeshPacket_msg, &p) || p.rx_time || p.rx_snr || p.priority || p.rx_rssi || p.delayed ||
182-
p.public_key.size || p.next_hop || p.relay_node || p.tx_after)
183-
return -1; // Reject: The input will not be added to the corpus.
184-
if (p.which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
185-
meshtastic_Data d;
186-
stream = pb_istream_from_buffer(p.decoded.payload.bytes, p.decoded.payload.size);
187-
if (!pb_decode(&stream, &meshtastic_Data_msg, &d))
188-
return -1; // Reject: The input will not be added to the corpus.
189-
}
170+
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t length) {
171+
meshtastic_MeshPacket p = meshtastic_MeshPacket_init_default;
172+
pb_istream_t stream = pb_istream_from_buffer(data, length);
173+
// Ignore any inputs that fail to decode or have fields set that are not transmitted over LoRa.
174+
if (!pb_decode(&stream, &meshtastic_MeshPacket_msg, &p) || p.rx_time || p.rx_snr || p.priority || p.rx_rssi || p.delayed || p.public_key.size ||
175+
p.next_hop || p.relay_node || p.tx_after)
176+
return -1; // Reject: The input will not be added to the corpus.
177+
if (p.which_payload_variant == meshtastic_MeshPacket_decoded_tag) {
178+
meshtastic_Data d;
179+
stream = pb_istream_from_buffer(p.decoded.payload.bytes, p.decoded.payload.size);
180+
if (!pb_decode(&stream, &meshtastic_Data_msg, &d))
181+
return -1; // Reject: The input will not be added to the corpus.
182+
}
190183

191-
// Provide default values for a few fields so the fuzzer doesn't need to guess them.
192-
if (p.from == 0)
193-
p.from = nodeDB->getNodeNum();
194-
if (p.to == 0)
195-
p.to = nodeDB->getNodeNum();
196-
static uint32_t packetId = 0;
197-
if (p.id == 0)
198-
p.id == ++packetId;
199-
if (p.pki_encrypted && config.security.admin_key_count)
200-
memcpy(&p.public_key, &config.security.admin_key[0], sizeof(p.public_key));
184+
// Provide default values for a few fields so the fuzzer doesn't need to guess them.
185+
if (p.from == 0)
186+
p.from = nodeDB->getNodeNum();
187+
if (p.to == 0)
188+
p.to = nodeDB->getNodeNum();
189+
static uint32_t packetId = 0;
190+
if (p.id == 0)
191+
p.id == ++packetId;
192+
if (p.pki_encrypted && config.security.admin_key_count)
193+
memcpy(&p.public_key, &config.security.admin_key[0], sizeof(p.public_key));
201194

202-
router->enqueueReceivedMessage(packetPool.allocCopy(p));
203-
runLoopOnce();
204-
return 0; // Accept: The input may be added to the corpus.
195+
router->enqueueReceivedMessage(packetPool.allocCopy(p));
196+
runLoopOnce();
197+
return 0; // Accept: The input may be added to the corpus.
205198
}
206199
}

0 commit comments

Comments
 (0)