libsnapshot_fuzzer: construct valid super partition metadata.

This should hopefully achieve more coverage.

Test: pass
Bug: 154633114
Change-Id: Ice575f2d8c3e22b80465c133d055e7c4368ebdfa
This commit is contained in:
Yifan Hong 2020-04-30 17:06:37 -07:00
parent 74d1fb4571
commit db0e62b87a
3 changed files with 57 additions and 1 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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 {