Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc3531f7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Adding binder2corpus to generate fuzzer corpus" into main am:...

Merge "Adding binder2corpus to generate fuzzer corpus" into main am: 010bbe81 am: d7cde53b am: 969fcde5

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2700616



Change-Id: Idea0da57539e4aa915f1f641836db8b59cb5cd33
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 8c07382e 969fcde5
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -129,3 +129,18 @@ cc_library {
    ],
    ],
    export_include_dirs: ["include_random_parcel_seeds"],
    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",
    ],
}
+31 −0
Original line number Original line 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
+90 −0
Original line number Original line 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;
}