blob: 5310507d3b2bbd369de66b1b3d36677696632da6 [file] [log] [blame]
Tri Vo77e0ca02016-12-05 10:08:59 -08001/*
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
Tri Vo77e0ca02016-12-05 10:08:59 -080017#include "ProtoFuzzerMutator.h"
18
Tri Vo77e0ca02016-12-05 10:08:59 -080019#include "test/vts/proto/ComponentSpecificationMessage.pb.h"
20
21#include <unistd.h>
22
Tri Voc8bfd0d2017-07-24 15:31:46 -070023#include <cstdlib>
Tri Vo77e0ca02016-12-05 10:08:59 -080024#include <iostream>
25#include <memory>
26#include <string>
27#include <vector>
28
Tri Vo77e0ca02016-12-05 10:08:59 -080029using std::cout;
30using std::endl;
31using std::make_unique;
Tri Vo826a2012017-01-05 12:21:25 -080032using std::string;
Tri Vo77e0ca02016-12-05 10:08:59 -080033using std::unique_ptr;
34using std::vector;
35
36namespace android {
37namespace vts {
Tri Vo70c1ab62017-03-15 09:19:10 -070038namespace fuzzer {
Tri Vo77e0ca02016-12-05 10:08:59 -080039
Tri Vo16eed232017-03-08 08:52:15 -080040// 64-bit random number generator.
Tri Vo624961d2017-07-24 10:30:41 -070041static unique_ptr<Random> random;
Tri Vo9f5fd852017-05-20 12:32:26 -070042// Parameters that were passed in to fuzzer.
Tri Vo16eed232017-03-08 08:52:15 -080043static ProtoFuzzerParams params;
Tri Vo16eed232017-03-08 08:52:15 -080044// Used to mutate inputs to hal driver.
Tri Vo77e0ca02016-12-05 10:08:59 -080045static unique_ptr<ProtoFuzzerMutator> mutator;
Tri Vo9f5fd852017-05-20 12:32:26 -070046// Used to exercise HIDL HAL's API.
47static unique_ptr<ProtoFuzzerRunner> runner;
Tri Vo77e0ca02016-12-05 10:08:59 -080048
Tri Vof4037d42017-03-31 17:28:25 -070049static ProtoFuzzerMutatorConfig mutator_config{
Tri Voced79542017-01-26 15:01:09 -080050 // Heuristic: values close to 0 are likely to be meaningful scalar input
51 // values.
52 [](Random &rand) {
53 size_t dice_roll = rand(10);
54 if (dice_roll < 3) {
55 // With probability of 30% return an integer in range [0, 10).
56 return rand(10);
57 } else if (dice_roll >= 3 && dice_roll < 6) {
58 // With probability of 30% return an integer in range [0, 100).
59 return rand(100);
60 } else if (dice_roll >= 6 && dice_roll < 9) {
61 // With probability of 30% return an integer in range [0, 100).
62 return rand(1000);
63 }
64 if (rand(10) == 0) {
65 // With probability of 1% return 0xffffffffffffffff.
66 return 0xffffffffffffffff;
67 }
68 // With probability 9% result is uniformly random.
69 return rand.Rand();
70 },
71 // Odds of an enum being treated like a scalar are 1:1000.
72 {1, 1000}};
73
Tri Voc8bfd0d2017-07-24 15:31:46 -070074// Executed when fuzzer process exits. We use this to print out useful
75// information about the state of the fuzzer.
76static void AtExit() {
77 // Print currently opened interfaces.
78 cerr << "Currently opened interfaces: " << endl;
79 for (const auto &iface_desc : runner->GetOpenedIfaces()) {
80 cerr << iface_desc.first << endl;
81 }
Tri Vof657d672017-07-26 16:13:02 -070082 cerr << endl;
83 cerr << runner->GetStats().StatsString();
Tri Voc8bfd0d2017-07-24 15:31:46 -070084}
85
Tri Vo77e0ca02016-12-05 10:08:59 -080086extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
Tri Vo16eed232017-03-08 08:52:15 -080087 params = ExtractProtoFuzzerParams(*argc, *argv);
Tri Vo624961d2017-07-24 10:30:41 -070088 cerr << params.DebugString() << endl;
89
90 random = make_unique<Random>(params.seed_);
Tri Vo826a2012017-01-05 12:21:25 -080091 mutator = make_unique<ProtoFuzzerMutator>(
Tri Vo624961d2017-07-24 10:30:41 -070092 *random.get(), ExtractPredefinedTypes(params.comp_specs_),
93 mutator_config);
Tri Vo9f5fd852017-05-20 12:32:26 -070094 runner = make_unique<ProtoFuzzerRunner>(params.comp_specs_);
95
96 runner->Init(params.target_iface_, params.binder_mode_);
Tri Voc8bfd0d2017-07-24 15:31:46 -070097 // Register atexit handler after all static objects' initialization.
98 std::atexit(AtExit);
Tri Vo77e0ca02016-12-05 10:08:59 -080099 return 0;
100}
101
102extern "C" size_t LLVMFuzzerCustomMutator(uint8_t *data, size_t size,
103 size_t max_size, unsigned int seed) {
Tri Vo9f5fd852017-05-20 12:32:26 -0700104 ExecSpec exec_spec{};
Tri Vod0229fb2017-08-10 17:27:49 -0700105 // An Execution is randomly generated if:
106 // 1. It can't be serialized from the given buffer OR
107 // 2. The runner has opened interfaces that have not been touched.
108 // Otherwise, the Execution is mutated.
109 if (!FromArray(data, size, &exec_spec) || runner->UntouchedIfaces()) {
Tri Vo16eed232017-03-08 08:52:15 -0800110 exec_spec =
Tri Vo9f5fd852017-05-20 12:32:26 -0700111 mutator->RandomGen(runner->GetOpenedIfaces(), params.exec_size_);
Tri Vo77e0ca02016-12-05 10:08:59 -0800112 } else {
Tri Vo9f5fd852017-05-20 12:32:26 -0700113 mutator->Mutate(runner->GetOpenedIfaces(), &exec_spec);
Tri Vo77e0ca02016-12-05 10:08:59 -0800114 }
Tri Vodfe95ea2017-06-07 17:52:10 -0700115 return ToArray(data, size, &exec_spec);
Tri Vo77e0ca02016-12-05 10:08:59 -0800116}
117
Tri Vo826a2012017-01-05 12:21:25 -0800118// TODO(trong): implement a meaningful cross-over mechanism.
Tri Vo77e0ca02016-12-05 10:08:59 -0800119size_t LLVMFuzzerCustomCrossOver(const uint8_t *data1, size_t size1,
120 const uint8_t *data2, size_t size2,
121 uint8_t *out, size_t max_out_size,
122 unsigned int seed) {
123 memcpy(out, data1, size1);
124 return size1;
125}
126
127extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
Tri Vodfe95ea2017-06-07 17:52:10 -0700128 ExecSpec exec_spec{};
129 if (!FromArray(data, size, &exec_spec)) {
130 cerr << "Failed to deserialize an ExecSpec." << endl;
Tri Vo77e0ca02016-12-05 10:08:59 -0800131 return 0;
132 }
Tri Vo9f5fd852017-05-20 12:32:26 -0700133 runner->Execute(exec_spec);
Tri Vo77e0ca02016-12-05 10:08:59 -0800134 return 0;
135}
136
Tri Vo70c1ab62017-03-15 09:19:10 -0700137} // namespace fuzzer
Tri Vo77e0ca02016-12-05 10:08:59 -0800138} // namespace vts
139} // namespace android