diff options
author | 2023-08-10 22:38:08 +0000 | |
---|---|---|
committer | 2023-08-10 22:38:08 +0000 | |
commit | 010bbe81afb77bcc839214a9aece9341bd21901c (patch) | |
tree | f2a8e47f12345c06e9b3c75329d411d441fbdbc0 | |
parent | 493aca05860f58dd956e5121935078c83b6f3dd2 (diff) | |
parent | 391ead5b5ab41933582f28e480a69901f0f27a5c (diff) |
Merge "Adding binder2corpus to generate fuzzer corpus" into main
-rw-r--r-- | libs/binder/tests/parcel_fuzzer/Android.bp | 15 | ||||
-rw-r--r-- | libs/binder/tests/parcel_fuzzer/binder2corpus/README.md | 31 | ||||
-rw-r--r-- | libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp | 90 |
3 files changed, 136 insertions, 0 deletions
diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp index 0d1503eda0..383795eff5 100644 --- a/libs/binder/tests/parcel_fuzzer/Android.bp +++ b/libs/binder/tests/parcel_fuzzer/Android.bp @@ -129,3 +129,18 @@ cc_library { ], export_include_dirs: ["include_random_parcel_seeds"], } + +cc_binary_host { + name: "binder2corpus", + static_libs: [ + "libbinder_random_parcel_seeds", + ], + srcs: [ + "binder2corpus/binder2corpus.cpp", + ], + shared_libs: [ + "libbase", + "libbinder", + "libutils", + ], +} diff --git a/libs/binder/tests/parcel_fuzzer/binder2corpus/README.md b/libs/binder/tests/parcel_fuzzer/binder2corpus/README.md new file mode 100644 index 0000000000..59bf9f31c0 --- /dev/null +++ b/libs/binder/tests/parcel_fuzzer/binder2corpus/README.md @@ -0,0 +1,31 @@ +# binder2corpus + +This tool converts recordings generated by record_binder tool to fuzzer seeds for fuzzService. + +# Steps to add corpus: + +## Start recording the service binder +ex. record_binder start manager + +## Run test on device or keep device idle +ex. atest servicemanager_test + +## Stop the recording +record_binder stop manager + +## Pull the recording on host +Recordings are present on device at /data/local/recordings/<service_name>. Use adb pull. +Use inspect command of record_binder to check if there are some transactions captured. +ex. record_binder inspect manager + +## run corpus generator tool +binder2corpus <recording_path> <dir_to_write_corpus> + +## Build fuzzer and sync data directory +ex. m servicemanager_fuzzer && adb sync data + +## Push corpus on device +ex. adb push servicemanager_fuzzer_corpus/ /data/fuzz/x86_64/servicemanager_fuzzer/ + +## Run fuzzer with corpus directory as argument +ex. adb shell /data/fuzz/x86_64/servicemanager_fuzzer/servicemanager_fuzzer /data/fuzz/x86_64/servicemanager_fuzzer/servicemanager_fuzzer_corpus
\ No newline at end of file diff --git a/libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp b/libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp new file mode 100644 index 0000000000..c0fdaea0a8 --- /dev/null +++ b/libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2023 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 <android-base/file.h> +#include <android-base/logging.h> +#include <android-base/unique_fd.h> +#include <binder/RecordedTransaction.h> + +#include <fuzzseeds/random_parcel_seeds.h> + +#include <sys/prctl.h> + +using android::generateSeedsFromRecording; +using android::status_t; +using android::base::unique_fd; +using android::binder::debug::RecordedTransaction; + +status_t generateCorpus(const char* recordingPath, const char* corpusDir) { + unique_fd fd(open(recordingPath, O_RDONLY)); + if (!fd.ok()) { + std::cerr << "Failed to open recording file at path " << recordingPath + << " with error: " << strerror(errno) << '\n'; + return android::BAD_VALUE; + } + + if (auto res = mkdir(corpusDir, 0766); res != 0) { + std::cerr + << "Failed to create corpus directory at path. Delete directory if already exists: " + << corpusDir << std::endl; + return android::BAD_VALUE; + } + + int transactionNumber = 0; + while (auto transaction = RecordedTransaction::fromFile(fd)) { + ++transactionNumber; + std::string filePath = std::string(corpusDir) + std::string("transaction_") + + std::to_string(transactionNumber); + constexpr int openFlags = O_WRONLY | O_CREAT | O_BINARY | O_CLOEXEC; + android::base::unique_fd corpusFd(open(filePath.c_str(), openFlags, 0666)); + if (!corpusFd.ok()) { + std::cerr << "Failed to open fd. Path " << filePath + << " with error: " << strerror(errno) << std::endl; + return android::UNKNOWN_ERROR; + } + generateSeedsFromRecording(corpusFd, transaction.value()); + } + + if (transactionNumber == 0) { + std::cerr << "No valid transaction has been found in recording file: " << recordingPath + << std::endl; + return android::BAD_VALUE; + } + + return android::NO_ERROR; +} + +void printHelp(const char* toolName) { + std::cout << "Usage: \n\n" + << toolName + << " <recording_path> <destination_directory> \n\n*Use " + "record_binder tool for recording binder transactions." + << std::endl; +} + +int main(int argc, char** argv) { + if (argc != 3) { + printHelp(argv[0]); + return 1; + } + const char* sourcePath = argv[1]; + const char* corpusDir = argv[2]; + if (android::NO_ERROR != generateCorpus(sourcePath, corpusDir)) { + std::cerr << "Failed to generate fuzzer corpus." << std::endl; + return 1; + } + return 0; +} |