1*7eba2f3bSAndroid Build Coastguard Worker #include "fuzz_cmn.h"
2*7eba2f3bSAndroid Build Coastguard Worker
BytesToHex(const uint8_t * data,size_t size)3*7eba2f3bSAndroid Build Coastguard Worker std::string BytesToHex(const uint8_t* data, size_t size) {
4*7eba2f3bSAndroid Build Coastguard Worker std::string result = "{";
5*7eba2f3bSAndroid Build Coastguard Worker if (data && size) {
6*7eba2f3bSAndroid Build Coastguard Worker StringAppendF(&result, "0x%02X", data[0]);
7*7eba2f3bSAndroid Build Coastguard Worker for (auto i = 1; i < size; i++) {
8*7eba2f3bSAndroid Build Coastguard Worker StringAppendF(&result, ", 0x%02X", data[i]);
9*7eba2f3bSAndroid Build Coastguard Worker }
10*7eba2f3bSAndroid Build Coastguard Worker }
11*7eba2f3bSAndroid Build Coastguard Worker result += "}";
12*7eba2f3bSAndroid Build Coastguard Worker
13*7eba2f3bSAndroid Build Coastguard Worker return result;
14*7eba2f3bSAndroid Build Coastguard Worker }
15*7eba2f3bSAndroid Build Coastguard Worker
BytesToHex(const bytes_t & data)16*7eba2f3bSAndroid Build Coastguard Worker std::string BytesToHex(const bytes_t& data) {
17*7eba2f3bSAndroid Build Coastguard Worker return BytesToHex(&data[0], data.size());
18*7eba2f3bSAndroid Build Coastguard Worker }
19*7eba2f3bSAndroid Build Coastguard Worker
UnpackPackets(const uint8_t * Data,size_t Size)20*7eba2f3bSAndroid Build Coastguard Worker static std::vector<bytes_t> UnpackPackets(const uint8_t* Data, size_t Size) {
21*7eba2f3bSAndroid Build Coastguard Worker std::vector<bytes_t> result;
22*7eba2f3bSAndroid Build Coastguard Worker while (Size > 0) {
23*7eba2f3bSAndroid Build Coastguard Worker auto s = *Data++;
24*7eba2f3bSAndroid Build Coastguard Worker Size--;
25*7eba2f3bSAndroid Build Coastguard Worker
26*7eba2f3bSAndroid Build Coastguard Worker if (s > Size) {
27*7eba2f3bSAndroid Build Coastguard Worker s = Size;
28*7eba2f3bSAndroid Build Coastguard Worker }
29*7eba2f3bSAndroid Build Coastguard Worker
30*7eba2f3bSAndroid Build Coastguard Worker if (s > 0) {
31*7eba2f3bSAndroid Build Coastguard Worker result.push_back(bytes_t(Data, Data + s));
32*7eba2f3bSAndroid Build Coastguard Worker }
33*7eba2f3bSAndroid Build Coastguard Worker
34*7eba2f3bSAndroid Build Coastguard Worker Size -= s;
35*7eba2f3bSAndroid Build Coastguard Worker Data += s;
36*7eba2f3bSAndroid Build Coastguard Worker }
37*7eba2f3bSAndroid Build Coastguard Worker
38*7eba2f3bSAndroid Build Coastguard Worker return result;
39*7eba2f3bSAndroid Build Coastguard Worker }
40*7eba2f3bSAndroid Build Coastguard Worker
PackPackets(const std::vector<bytes_t> & Packets,uint8_t * Data,size_t MaxSize)41*7eba2f3bSAndroid Build Coastguard Worker static size_t PackPackets(const std::vector<bytes_t>& Packets, uint8_t* Data,
42*7eba2f3bSAndroid Build Coastguard Worker size_t MaxSize) {
43*7eba2f3bSAndroid Build Coastguard Worker size_t TotalSize = 0;
44*7eba2f3bSAndroid Build Coastguard Worker
45*7eba2f3bSAndroid Build Coastguard Worker for (auto it = Packets.cbegin(); MaxSize > 0 && it != Packets.cend(); ++it) {
46*7eba2f3bSAndroid Build Coastguard Worker auto s = it->size();
47*7eba2f3bSAndroid Build Coastguard Worker if (s == 0) {
48*7eba2f3bSAndroid Build Coastguard Worker // skip empty packets
49*7eba2f3bSAndroid Build Coastguard Worker continue;
50*7eba2f3bSAndroid Build Coastguard Worker }
51*7eba2f3bSAndroid Build Coastguard Worker
52*7eba2f3bSAndroid Build Coastguard Worker if (s > MaxSize - 1) {
53*7eba2f3bSAndroid Build Coastguard Worker s = MaxSize - 1;
54*7eba2f3bSAndroid Build Coastguard Worker }
55*7eba2f3bSAndroid Build Coastguard Worker *Data++ = (uint8_t)s;
56*7eba2f3bSAndroid Build Coastguard Worker MaxSize--;
57*7eba2f3bSAndroid Build Coastguard Worker
58*7eba2f3bSAndroid Build Coastguard Worker memcpy(Data, it->data(), s);
59*7eba2f3bSAndroid Build Coastguard Worker MaxSize -= s;
60*7eba2f3bSAndroid Build Coastguard Worker Data += s;
61*7eba2f3bSAndroid Build Coastguard Worker
62*7eba2f3bSAndroid Build Coastguard Worker TotalSize += (s + 1);
63*7eba2f3bSAndroid Build Coastguard Worker }
64*7eba2f3bSAndroid Build Coastguard Worker
65*7eba2f3bSAndroid Build Coastguard Worker return TotalSize;
66*7eba2f3bSAndroid Build Coastguard Worker }
67*7eba2f3bSAndroid Build Coastguard Worker
LLVMFuzzerCustomMutator(uint8_t * Data,size_t Size,size_t MaxSize,uint Seed)68*7eba2f3bSAndroid Build Coastguard Worker extern "C" size_t LLVMFuzzerCustomMutator(uint8_t* Data, size_t Size,
69*7eba2f3bSAndroid Build Coastguard Worker size_t MaxSize, uint Seed) {
70*7eba2f3bSAndroid Build Coastguard Worker const uint MAX_PACKET_SIZE = 255;
71*7eba2f3bSAndroid Build Coastguard Worker auto Packets = UnpackPackets(Data, Size);
72*7eba2f3bSAndroid Build Coastguard Worker auto odd = Seed % 100;
73*7eba2f3bSAndroid Build Coastguard Worker if (odd < 10 || Packets.size() == 0) {
74*7eba2f3bSAndroid Build Coastguard Worker // ~10% chance to insert a new packet
75*7eba2f3bSAndroid Build Coastguard Worker auto len = (Seed >> 8) % MAX_PACKET_SIZE;
76*7eba2f3bSAndroid Build Coastguard Worker if (Packets.size() > 0) {
77*7eba2f3bSAndroid Build Coastguard Worker auto pos = (Seed >> 16) % Packets.size();
78*7eba2f3bSAndroid Build Coastguard Worker Packets.insert(Packets.begin() + pos, bytes_t(len));
79*7eba2f3bSAndroid Build Coastguard Worker } else {
80*7eba2f3bSAndroid Build Coastguard Worker Packets.push_back(bytes_t(len));
81*7eba2f3bSAndroid Build Coastguard Worker }
82*7eba2f3bSAndroid Build Coastguard Worker } else if (odd < 20 && Packets.size() > 1) {
83*7eba2f3bSAndroid Build Coastguard Worker // ~10% chance to drop a packet
84*7eba2f3bSAndroid Build Coastguard Worker auto pos = (Seed >> 16) % Packets.size();
85*7eba2f3bSAndroid Build Coastguard Worker Packets.erase(Packets.begin() + pos);
86*7eba2f3bSAndroid Build Coastguard Worker } else if (Packets.size() > 0) {
87*7eba2f3bSAndroid Build Coastguard Worker // ~80% chance to mutate a packet, maximium length 255
88*7eba2f3bSAndroid Build Coastguard Worker auto pos = (Seed >> 16) % Packets.size();
89*7eba2f3bSAndroid Build Coastguard Worker auto& p = Packets[pos];
90*7eba2f3bSAndroid Build Coastguard Worker
91*7eba2f3bSAndroid Build Coastguard Worker auto size = p.size();
92*7eba2f3bSAndroid Build Coastguard Worker p.resize(MAX_PACKET_SIZE);
93*7eba2f3bSAndroid Build Coastguard Worker size = LLVMFuzzerMutate(p.data(), size, MAX_PACKET_SIZE);
94*7eba2f3bSAndroid Build Coastguard Worker p.resize(size);
95*7eba2f3bSAndroid Build Coastguard Worker }
96*7eba2f3bSAndroid Build Coastguard Worker
97*7eba2f3bSAndroid Build Coastguard Worker Fuzz_FixPackets(Packets, Seed);
98*7eba2f3bSAndroid Build Coastguard Worker
99*7eba2f3bSAndroid Build Coastguard Worker Size = PackPackets(Packets, Data, MaxSize);
100*7eba2f3bSAndroid Build Coastguard Worker FUZZLOG("Packet size:%zu, data=%s", Packets.size(),
101*7eba2f3bSAndroid Build Coastguard Worker BytesToHex(Data, Size).c_str());
102*7eba2f3bSAndroid Build Coastguard Worker return Size;
103*7eba2f3bSAndroid Build Coastguard Worker }
104*7eba2f3bSAndroid Build Coastguard Worker
LLVMFuzzerTestOneInput(const uint8_t * Data,size_t Size)105*7eba2f3bSAndroid Build Coastguard Worker extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
106*7eba2f3bSAndroid Build Coastguard Worker android::base::SetDefaultTag(fuzzer_name);
107*7eba2f3bSAndroid Build Coastguard Worker
108*7eba2f3bSAndroid Build Coastguard Worker if (Size > 0) {
109*7eba2f3bSAndroid Build Coastguard Worker auto Packets = UnpackPackets(Data, Size);
110*7eba2f3bSAndroid Build Coastguard Worker Fuzz_RunPackets(Packets);
111*7eba2f3bSAndroid Build Coastguard Worker }
112*7eba2f3bSAndroid Build Coastguard Worker
113*7eba2f3bSAndroid Build Coastguard Worker if (__gcov_flush) {
114*7eba2f3bSAndroid Build Coastguard Worker __gcov_flush();
115*7eba2f3bSAndroid Build Coastguard Worker }
116*7eba2f3bSAndroid Build Coastguard Worker
117*7eba2f3bSAndroid Build Coastguard Worker return 0;
118*7eba2f3bSAndroid Build Coastguard Worker }
119*7eba2f3bSAndroid Build Coastguard Worker
LLVMFuzzerInitialize(int *,char ***)120*7eba2f3bSAndroid Build Coastguard Worker extern "C" int LLVMFuzzerInitialize(int* /*argc*/, char*** /*argv*/) {
121*7eba2f3bSAndroid Build Coastguard Worker android::base::SetMinimumLogSeverity(android::base::DEBUG);
122*7eba2f3bSAndroid Build Coastguard Worker FUZZLOG("Debugging output enabled");
123*7eba2f3bSAndroid Build Coastguard Worker
124*7eba2f3bSAndroid Build Coastguard Worker return 0;
125*7eba2f3bSAndroid Build Coastguard Worker }
126