1 /*
2 * Copyright (C) 2022 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 <fuzzer/FuzzedDataProvider.h>
18 #include <hidl/metadata.h>
19 #include <import_parser.h>
20 #include <interface_utils.h>
21 #include <rlimit_parser.h>
22
23 using namespace android;
24 using namespace android::init;
25
26 const std::vector<std::string> kValidInputs[] = {
27 {"", "cpu", "10", "10"}, {"", "RLIM_CPU", "10", "10"}, {"", "12", "unlimited", "10"},
28 {"", "13", "-1", "10"}, {"", "14", "10", "unlimited"}, {"", "15", "10", "-1"},
29 };
30
31 const std::string kValidPaths[] = {
32 "/system/etc/init/hw/init.rc",
33 "/system/etc/init",
34 };
35
36 const int32_t kMaxBytes = 256;
37 const std::string kValidInterfaces = "android.frameworks.vr.composer@2.0::IVrComposerClient";
38
39 class InitParserFuzzer {
40 public:
InitParserFuzzer(const uint8_t * data,size_t size)41 InitParserFuzzer(const uint8_t* data, size_t size) : fdp_(data, size){};
42 void Process();
43
44 private:
45 void InvokeParser();
46 void InvokeLimitParser();
47 void InvokeInterfaceUtils();
48 InterfaceInheritanceHierarchyMap GenerateHierarchyMap();
49 std::vector<HidlInterfaceMetadata> GenerateInterfaceMetadata();
50
51 FuzzedDataProvider fdp_;
52 };
53
InvokeLimitParser()54 void InitParserFuzzer::InvokeLimitParser() {
55 if (fdp_.ConsumeBool()) {
56 std::vector<std::string> input;
57 input.push_back("");
58 input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
59 input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
60 input.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
61 ParseRlimit(input);
62 } else {
63 ParseRlimit(fdp_.PickValueInArray(kValidInputs));
64 }
65 }
66
GenerateInterfaceMetadata()67 std::vector<HidlInterfaceMetadata> InitParserFuzzer::GenerateInterfaceMetadata() {
68 std::vector<HidlInterfaceMetadata> random_interface;
69 for (size_t idx = 0; idx < fdp_.ConsumeIntegral<size_t>(); ++idx) {
70 HidlInterfaceMetadata metadata;
71 metadata.name = fdp_.ConsumeRandomLengthString(kMaxBytes);
72 for (size_t idx1 = 0; idx1 < fdp_.ConsumeIntegral<size_t>(); ++idx1) {
73 metadata.inherited.push_back(fdp_.ConsumeRandomLengthString(kMaxBytes));
74 }
75 random_interface.push_back(metadata);
76 }
77 return random_interface;
78 }
79
GenerateHierarchyMap()80 InterfaceInheritanceHierarchyMap InitParserFuzzer::GenerateHierarchyMap() {
81 InterfaceInheritanceHierarchyMap result;
82 std::vector<HidlInterfaceMetadata> random_interface;
83 if (fdp_.ConsumeBool()) {
84 random_interface = GenerateInterfaceMetadata();
85 } else {
86 random_interface = HidlInterfaceMetadata::all();
87 }
88
89 for (const HidlInterfaceMetadata& iface : random_interface) {
90 std::set<FQName> inherited_interfaces;
91 for (const std::string& intf : iface.inherited) {
92 FQName fqname;
93 (void)fqname.setTo(intf);
94 inherited_interfaces.insert(fqname);
95 }
96 FQName fqname;
97 (void)fqname.setTo(iface.name);
98 result[fqname] = inherited_interfaces;
99 }
100 return result;
101 }
102
InvokeInterfaceUtils()103 void InitParserFuzzer::InvokeInterfaceUtils() {
104 InterfaceInheritanceHierarchyMap hierarchy_map = GenerateHierarchyMap();
105 SetKnownInterfaces(hierarchy_map);
106 IsKnownInterface(fdp_.ConsumeRandomLengthString(kMaxBytes));
107 std::set<std::string> interface_set;
108 for (size_t idx = 0; idx < fdp_.ConsumeIntegral<size_t>(); ++idx) {
109 auto set_interface_values = fdp_.PickValueInArray<const std::function<void()>>({
110 [&]() {
111 interface_set.insert(("aidl/" + fdp_.ConsumeRandomLengthString(kMaxBytes)));
112 },
113 [&]() { interface_set.insert(fdp_.ConsumeRandomLengthString(kMaxBytes)); },
114 [&]() { interface_set.insert(kValidInterfaces); },
115 });
116 set_interface_values();
117 }
118 CheckInterfaceInheritanceHierarchy(interface_set, hierarchy_map);
119 }
120
InvokeParser()121 void InitParserFuzzer::InvokeParser() {
122 Parser parser;
123 std::string name = fdp_.ConsumeBool() ? fdp_.ConsumeRandomLengthString(kMaxBytes) : "import";
124 parser.AddSectionParser(name, std::make_unique<ImportParser>(&parser));
125 std::string path = fdp_.ConsumeBool() ? fdp_.PickValueInArray(kValidPaths)
126 : fdp_.ConsumeRandomLengthString(kMaxBytes);
127 parser.ParseConfig(path);
128 parser.ParseConfigFileInsecure(path, false /* follow_symlinks */);
129 }
130
Process()131 void InitParserFuzzer::Process() {
132 while (fdp_.remaining_bytes()) {
133 auto invoke_parser_fuzzer = fdp_.PickValueInArray<const std::function<void()>>({
134 [&]() { InvokeParser(); },
135 [&]() { InvokeInterfaceUtils(); },
136 [&]() { InvokeLimitParser(); },
137 });
138 invoke_parser_fuzzer();
139 }
140 }
141
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)142 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
143 InitParserFuzzer init_parser_fuzzer(data, size);
144 init_parser_fuzzer.Process();
145 return 0;
146 }
147