libsnapshot: fix incorrect assumption of cow images

libsnapshot used to assume CoW images are always mapped
with device mapper, and call GetDeviceString directly.
However, in tests, it is possible that it is mapped as loop
devices. Fix the incorrect assumption and calls
IImageManager::GetMappedImageDevice instead.

Test: libsnapshot_fuzzer with corpus
Bug: 154633114
Change-Id: I1ec39744480e514ae7a7902643ed863e0ca0a340
(cherry picked from commit e6c1a84276)
Merged-In: I1ec39744480e514ae7a7902643ed863e0ca0a340
This commit is contained in:
Yifan Hong 2020-05-04 16:59:27 -07:00
parent 9842adf768
commit 82035d6b82
2 changed files with 26 additions and 4 deletions

View File

@ -536,6 +536,10 @@ class SnapshotManager final {
bool ProcessUpdateStateOnDataWipe(bool allow_forward_merge,
const std::function<bool()>& callback);
// Return device string of a mapped image, or if it is not available, the mapped image path.
bool GetMappedImageDeviceStringOrPath(const std::string& device_name,
std::string* device_string_or_mapped_path);
std::string gsid_dir_;
std::string metadata_dir_;
std::unique_ptr<IDeviceInfo> device_;

View File

@ -1674,7 +1674,7 @@ bool SnapshotManager::MapPartitionWithSnapshot(LockedFile* lock,
return false;
}
std::string cow_device;
if (!dm.GetDeviceString(cow_name, &cow_device)) {
if (!GetMappedImageDeviceStringOrPath(cow_name, &cow_device)) {
LOG(ERROR) << "Could not determine major/minor for: " << cow_name;
return false;
}
@ -1771,7 +1771,7 @@ bool SnapshotManager::MapCowDevices(LockedFile* lock, const CreateLogicalPartiti
// If the COW image exists, append it as the last extent.
if (snapshot_status.cow_file_size() > 0) {
std::string cow_image_device;
if (!dm.GetDeviceString(cow_image_name, &cow_image_device)) {
if (!GetMappedImageDeviceStringOrPath(cow_image_name, &cow_image_device)) {
LOG(ERROR) << "Cannot determine major/minor for: " << cow_image_name;
return false;
}
@ -2347,7 +2347,6 @@ Return SnapshotManager::InitializeUpdateSnapshots(
const std::map<std::string, SnapshotStatus>& all_snapshot_status) {
CHECK(lock);
auto& dm = DeviceMapper::Instance();
CreateLogicalPartitionParams cow_params{
.block_device = LP_METADATA_DEFAULT_PARTITION_NAME,
.metadata = exported_target_metadata,
@ -2372,7 +2371,7 @@ Return SnapshotManager::InitializeUpdateSnapshots(
}
std::string cow_path;
if (!dm.GetDmDevicePathByName(cow_name, &cow_path)) {
if (!images_->GetMappedImageDevice(cow_name, &cow_path)) {
LOG(ERROR) << "Cannot determine path for " << cow_name;
return Return::Error();
}
@ -2685,5 +2684,24 @@ bool SnapshotManager::UpdateForwardMergeIndicator(bool wipe) {
return true;
}
bool SnapshotManager::GetMappedImageDeviceStringOrPath(const std::string& device_name,
std::string* device_string_or_mapped_path) {
auto& dm = DeviceMapper::Instance();
// Try getting the device string if it is a device mapper device.
if (dm.GetState(device_name) != DmDeviceState::INVALID) {
return dm.GetDeviceString(device_name, device_string_or_mapped_path);
}
// Otherwise, get path from IImageManager.
if (!images_->GetMappedImageDevice(device_name, device_string_or_mapped_path)) {
return false;
}
LOG(WARNING) << "Calling GetMappedImageDevice with local image manager; device "
<< (device_string_or_mapped_path ? *device_string_or_mapped_path : "(nullptr)")
<< "may not be available in first stage init! ";
return true;
}
} // namespace snapshot
} // namespace android