1 /*
2  * Copyright (C) 2019 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 "aidl.h"
18 #include "fake_io_delegate.h"
19 #include "options.h"
20 
21 #include <fuzzer/FuzzedDataProvider.h>
22 #include <iostream>
23 
24 #ifdef FUZZ_LOG
25 constexpr bool kFuzzLog = true;
26 #else
27 constexpr bool kFuzzLog = false;
28 #endif
29 
30 using android::aidl::test::FakeIoDelegate;
31 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)32 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
33   if (size <= 1) return 0;  // no use
34 
35   // b/145447540, large nested expressions sometimes hit the stack depth limit.
36   // Fuzzing things of this size don't provide any additional meaningful
37   // coverage. This is an approximate value which should allow us to explore all
38   // of the language w/o hitting a stack overflow.
39   if (size > 2000) return 0;
40 
41   FuzzedDataProvider provider = FuzzedDataProvider(data, size);
42   FakeIoDelegate io;
43   std::vector<std::string> args;
44 
45   size_t numArgs = provider.ConsumeIntegralInRange(0, 20);
46   for (size_t i = 0; i < numArgs; i++) {
47     args.emplace_back(provider.ConsumeRandomLengthString());
48   }
49 
50   while (provider.remaining_bytes() > 0) {
51     const std::string name = provider.ConsumeRandomLengthString();
52     const std::string contents = provider.ConsumeRandomLengthString();
53     io.SetFileContents(name, contents);
54   }
55 
56   if (kFuzzLog) {
57     std::cout << "cmd: ";
58     for (const std::string& arg : args) {
59       std::cout << arg << " ";
60     }
61     std::cout << std::endl;
62 
63     for (const auto& [f, input] : io.InputFiles()) {
64       std::cout << "INPUT " << f << ": " << input << std::endl;
65     }
66   }
67 
68   int ret = android::aidl::aidl_entry(Options::From(args), io);
69 
70   if (kFuzzLog) {
71     std::cout << "RET: " << ret << std::endl;
72     if (ret != 0) {
73       for (const auto& [f, output] : io.OutputFiles()) {
74         std::cout << "OUTPUT " << f << ": " << std::endl;
75         std::cout << output << std::endl;
76       }
77     }
78   }
79 
80   return 0;
81 }
82