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

Commit db0e62b8 authored by Yifan Hong's avatar Yifan Hong
Browse files

libsnapshot_fuzzer: construct valid super partition metadata.

This should hopefully achieve more coverage.

Test: pass
Bug: 154633114
Change-Id: Ice575f2d8c3e22b80465c133d055e7c4368ebdfa
parent 74d1fb45
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -77,7 +77,15 @@ message SnapshotManagerActionProto {
message SnapshotFuzzData {
    FuzzDeviceInfoData device_info_data = 1;
    FuzzSnapshotManagerData manager_data = 2;

    // If true:
    // - if super_data is empty, create empty super partition metadata.
    // - otherwise, create super partition metadata accordingly.
    // If false, no valid super partition metadata (it is zeroed)
    bool is_super_metadata_valid = 3;
    chromeos_update_engine.DeltaArchiveManifest super_data = 4;

    // More data used to prep the test before running actions.
    reserved 3 to 9999;
    reserved 5 to 9999;
    repeated SnapshotManagerActionProto actions = 10000;
}
+43 −0
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ using android::base::WriteStringToFile;
using android::dm::LoopControl;
using android::fiemap::IImageManager;
using android::fiemap::ImageManager;
using android::fs_mgr::BlockDeviceInfo;
using android::fs_mgr::IPartitionOpener;
using chromeos_update_engine::DynamicPartitionMetadata;

// This directory is exempted from pinning in ImageManager.
static const char MNT_DIR[] = "/data/gsi/ota/test/";
@@ -252,6 +255,7 @@ std::unique_ptr<AutoDevice> SnapshotFuzzEnv::CheckMapSuper(const std::string& fa
std::unique_ptr<ISnapshotManager> SnapshotFuzzEnv::CheckCreateSnapshotManager(
        const SnapshotFuzzData& data) {
    auto partition_opener = std::make_unique<TestPartitionOpener>(super());
    CheckWriteSuperMetadata(data, *partition_opener);
    auto metadata_dir = fake_root_->tmp_path() + "/snapshot_metadata";
    PCHECK(Mkdir(metadata_dir));

@@ -268,4 +272,43 @@ const std::string& SnapshotFuzzEnv::super() const {
    return fake_super_;
}

void SnapshotFuzzEnv::CheckWriteSuperMetadata(const SnapshotFuzzData& data,
                                              const IPartitionOpener& opener) {
    if (!data.is_super_metadata_valid()) {
        // Leave it zero.
        return;
    }

    BlockDeviceInfo super_device("super", SUPER_IMAGE_SIZE, 0, 0, 4096);
    std::vector<BlockDeviceInfo> devices = {super_device};
    auto builder = MetadataBuilder::New(devices, "super", 65536, 2);
    CHECK(builder != nullptr);

    // Attempt to create a super partition metadata using proto. All errors are ignored.
    for (const auto& group_proto : data.super_data().dynamic_partition_metadata().groups()) {
        (void)builder->AddGroup(group_proto.name(), group_proto.size());
        for (const auto& partition_name : group_proto.partition_names()) {
            (void)builder->AddPartition(partition_name, group_proto.name(),
                                        LP_PARTITION_ATTR_READONLY);
        }
    }

    for (const auto& partition_proto : data.super_data().partitions()) {
        auto p = builder->FindPartition(partition_proto.partition_name());
        if (p == nullptr) continue;
        (void)builder->ResizePartition(p, partition_proto.new_partition_info().size());
    }

    auto metadata = builder->Export();
    // metadata may be nullptr if it is not valid (e.g. partition name too long).
    // In this case, just use empty super partition data.
    if (metadata == nullptr) {
        builder = MetadataBuilder::New(devices, "super", 65536, 2);
        CHECK(builder != nullptr);
        metadata = builder->Export();
        CHECK(metadata != nullptr);
    }
    CHECK(FlashPartitionTable(opener, super(), *metadata.get()));
}

}  // namespace android::snapshot
+5 −0
Original line number Diff line number Diff line
@@ -16,8 +16,10 @@

#include <android-base/file.h>
#include <android-base/stringprintf.h>
#include <android/snapshot/snapshot_fuzz.pb.h>
#include <libdm/loop_control.h>
#include <libfiemap/image_manager.h>
#include <liblp/liblp.h>
#include <libsnapshot/auto_device.h>
#include <libsnapshot/test_helpers.h>

@@ -68,6 +70,9 @@ class SnapshotFuzzEnv {
    static std::unique_ptr<AutoDevice> CheckMapSuper(const std::string& fake_persist_path,
                                                     android::dm::LoopControl* control,
                                                     std::string* fake_super);

    void CheckWriteSuperMetadata(const SnapshotFuzzData& proto,
                                 const android::fs_mgr::IPartitionOpener& opener);
};

class SnapshotFuzzDeviceInfo : public ISnapshotManager::IDeviceInfo {