1 /*
2 * Copyright 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "ProtoFuzzerMutator.h"
18
19 #include "test/vts/proto/ComponentSpecificationMessage.pb.h"
20
21 #include <unistd.h>
22
23 #include <iostream>
24 #include <memory>
25 #include <string>
26 #include <vector>
27
28 using std::cout;
29 using std::endl;
30 using std::make_unique;
31 using std::string;
32 using std::unique_ptr;
33 using std::vector;
34
35 namespace android {
36 namespace vts {
37 namespace fuzzer {
38
39 // 64-bit random number generator.
40 static Random random{static_cast<uint64_t>(time(0))};
41 // Parameters that were passed in to fuzzer.
42 static ProtoFuzzerParams params;
43 // Used to mutate inputs to hal driver.
44 static unique_ptr<ProtoFuzzerMutator> mutator;
45 // Used to exercise HIDL HAL's API.
46 static unique_ptr<ProtoFuzzerRunner> runner;
47
48 static ProtoFuzzerMutatorConfig mutator_config{
49 // Heuristic: values close to 0 are likely to be meaningful scalar input
50 // values.
__anonc9cd82dc0102() 51 [](Random &rand) {
52 size_t dice_roll = rand(10);
53 if (dice_roll < 3) {
54 // With probability of 30% return an integer in range [0, 10).
55 return rand(10);
56 } else if (dice_roll >= 3 && dice_roll < 6) {
57 // With probability of 30% return an integer in range [0, 100).
58 return rand(100);
59 } else if (dice_roll >= 6 && dice_roll < 9) {
60 // With probability of 30% return an integer in range [0, 100).
61 return rand(1000);
62 }
63 if (rand(10) == 0) {
64 // With probability of 1% return 0xffffffffffffffff.
65 return 0xffffffffffffffff;
66 }
67 // With probability 9% result is uniformly random.
68 return rand.Rand();
69 },
70 // Odds of an enum being treated like a scalar are 1:1000.
__anonc9cd82dc0202() 71 {1, 1000}};
72
LLVMFuzzerInitialize(int * argc,char *** argv)73 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
74 params = ExtractProtoFuzzerParams(*argc, *argv);
75 mutator = make_unique<ProtoFuzzerMutator>(
76 random, ExtractPredefinedTypes(params.comp_specs_), mutator_config);
77 runner = make_unique<ProtoFuzzerRunner>(params.comp_specs_);
78
79 runner->Init(params.target_iface_, params.binder_mode_);
80 return 0;
81 }
82
LLVMFuzzerCustomMutator(uint8_t * data,size_t size,size_t max_size,unsigned int seed)83 extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size,
84 size_t max_size, unsigned int seed) {
85 ExecSpec exec_spec{};
86 if (!FromArray(data, size, &exec_spec)) {
87 exec_spec =
88 mutator->RandomGen(runner->GetOpenedIfaces(), params.exec_size_);
89 } else {
90 mutator->Mutate(runner->GetOpenedIfaces(), &exec_spec);
91 }
92 return ToArray(data, size, &exec_spec);
93 }
94
95 // TODO(trong): implement a meaningful cross-over mechanism.
LLVMFuzzerCustomCrossOver(const uint8_t * data1,size_t size1,const uint8_t * data2,size_t size2,uint8_t * out,size_t max_out_size,unsigned int seed)96 size_t LLVMFuzzerCustomCrossOver(const uint8_t *data1, size_t size1,
97 const uint8_t *data2, size_t size2,
98 uint8_t *out, size_t max_out_size,
99 unsigned int seed) {
100 memcpy(out, data1, size1);
101 return size1;
102 }
103
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)104 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
105 ExecSpec exec_spec{};
106 if (!FromArray(data, size, &exec_spec)) {
107 cerr << "Failed to deserialize an ExecSpec." << endl;
108 return 0;
109 }
110 runner->Execute(exec_spec);
111 return 0;
112 }
113
114 } // namespace fuzzer
115 } // namespace vts
116 } // namespace android
117