diff options
author | 2021-06-09 11:05:05 +0530 | |
---|---|---|
committer | 2021-06-25 10:36:29 +0530 | |
commit | 054c9365704c00e86f23f507fde102670e0894af (patch) | |
tree | ead0cae3863c79dd94affddc01dca0104ab16bd8 | |
parent | 538730970d090b3b49eb5d0fc902120190c243c8 (diff) |
Added cmd_fuzzer
Test: ./cmd_fuzzer
Bug: 187131591
Change-Id: Iac91b398366135bd87074881d3800c535e1dfc5f
-rw-r--r-- | cmds/cmd/fuzzer/Android.bp | 37 | ||||
-rw-r--r-- | cmds/cmd/fuzzer/README.md | 51 | ||||
-rw-r--r-- | cmds/cmd/fuzzer/cmd_fuzzer.cpp | 85 |
3 files changed, 173 insertions, 0 deletions
diff --git a/cmds/cmd/fuzzer/Android.bp b/cmds/cmd/fuzzer/Android.bp new file mode 100644 index 0000000000..0c78c5a18b --- /dev/null +++ b/cmds/cmd/fuzzer/Android.bp @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +cc_fuzz { + name: "cmd_fuzzer", + srcs: [ + "cmd_fuzzer.cpp", + ], + static_libs: [ + "libcmd", + "libutils", + "liblog", + "libselinux", + ], + shared_libs: [ + "libbinder", + ], + fuzz_config: { + cc: [ + "android-media-fuzzing-reports@google.com", + ], + componentid: 155276, + }, +} diff --git a/cmds/cmd/fuzzer/README.md b/cmds/cmd/fuzzer/README.md new file mode 100644 index 0000000000..db37ecea32 --- /dev/null +++ b/cmds/cmd/fuzzer/README.md @@ -0,0 +1,51 @@ +# Fuzzer for libcmd_fuzzer + +## Plugin Design Considerations +The fuzzer plugin for libcmd is designed based on the understanding of the library and tries to achieve the following: + +##### Maximize code coverage +The configuration parameters are not hardcoded, but instead selected based on +incoming data. This ensures more code paths are reached by the fuzzer. + +libcmd supports the following parameters: +1. In (parameter name: `in`) +2. Out (parameter name: `out`) +3. Err (parameter name: `err`) +4. Run Mode (parameter name: `runMode`) + +| Parameter| Valid Values| Configured Value| +|------------- |-------------| ----- | +| `in` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider| +| `out` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider| +| `err` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider| +| `runMode` | 1.`RunMode::kStandalone` 2. `RunMode::kLibrary` | Value chosen from valid values using FuzzedDataProvider| + +This also ensures that the plugin is always deterministic for any given input. + +##### Maximize utilization of input data +The plugin feeds the entire input data to the cmd module. +This ensures that the plugin tolerates any kind of input (empty, huge, +malformed, etc) and doesnt `exit()` on any input and thereby increasing the +chance of identifying vulnerabilities. + +## Build + +This describes steps to build cmd_fuzzer binary. + +### Android + +#### Steps to build +Build the fuzzer +``` + $ mm -j$(nproc) cmd_fuzzer +``` +#### Steps to run +To run on device +``` + $ adb sync data + $ adb shell /data/fuzz/${TARGET_ARCH}/cmd_fuzzer/cmd_fuzzer +``` + +## References: + * http://llvm.org/docs/LibFuzzer.html + * https://github.com/google/oss-fuzz diff --git a/cmds/cmd/fuzzer/cmd_fuzzer.cpp b/cmds/cmd/fuzzer/cmd_fuzzer.cpp new file mode 100644 index 0000000000..ab514a1d04 --- /dev/null +++ b/cmds/cmd/fuzzer/cmd_fuzzer.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <binder/TextOutput.h> +#include <cmd.h> +#include <fcntl.h> +#include <unistd.h> +#include <string> +#include <vector> + +#include <fuzzer/FuzzedDataProvider.h> + +using namespace std; +using namespace android; + +class TestTextOutput : public TextOutput { +public: + TestTextOutput() {} + virtual ~TestTextOutput() {} + + virtual status_t print(const char* /*txt*/, size_t /*len*/) { return NO_ERROR; } + virtual void moveIndent(int /*delta*/) { return; } + virtual void pushBundle() { return; } + virtual void popBundle() { return; } +}; + +class CmdFuzzer { +public: + void process(const uint8_t* data, size_t size); + +private: + FuzzedDataProvider* mFDP = nullptr; +}; + +void CmdFuzzer::process(const uint8_t* data, size_t size) { + mFDP = new FuzzedDataProvider(data, size); + vector<string> arguments; + if (mFDP->ConsumeBool()) { + if (mFDP->ConsumeBool()) { + arguments = {"-w", "media.aaudio"}; + } else { + arguments = {"-l"}; + } + } else { + while (mFDP->remaining_bytes() > 0) { + size_t sizestr = mFDP->ConsumeIntegralInRange<size_t>(1, mFDP->remaining_bytes()); + string argument = mFDP->ConsumeBytesAsString(sizestr); + arguments.emplace_back(argument); + } + } + vector<string_view> argSV; + for (auto& argument : arguments) { + argSV.emplace_back(argument.c_str()); + } + int32_t in = open("/dev/null", O_RDWR | O_CREAT); + int32_t out = open("/dev/null", O_RDWR | O_CREAT); + int32_t err = open("/dev/null", O_RDWR | O_CREAT); + TestTextOutput output; + TestTextOutput error; + RunMode runMode = mFDP->ConsumeBool() ? RunMode::kStandalone : RunMode::kLibrary; + cmdMain(argSV, output, error, in, out, err, runMode); + delete mFDP; + close(in); + close(out); + close(err); +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + CmdFuzzer cmdFuzzer; + cmdFuzzer.process(data, size); + return 0; +} |