Loading libs/binder/tests/parcel_fuzzer/Android.bp +15 −0 Original line number Diff line number Diff line Loading @@ -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", ], } libs/binder/tests/parcel_fuzzer/binder2corpus/README.md 0 → 100644 +31 −0 Original line number Diff line number Diff line # 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 libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * 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; } Loading
libs/binder/tests/parcel_fuzzer/Android.bp +15 −0 Original line number Diff line number Diff line Loading @@ -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", ], }
libs/binder/tests/parcel_fuzzer/binder2corpus/README.md 0 → 100644 +31 −0 Original line number Diff line number Diff line # 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
libs/binder/tests/parcel_fuzzer/binder2corpus/binder2corpus.cpp 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * 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; }