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

Commit 3013e6ef authored by Yifan Hong's avatar Yifan Hong
Browse files

libsnapshot_fuzzer: Properly unmap images

Instead of unsetting gsid.mapped_images.* directly, properly unmap
them through image manager. This also avoids interference between
different fuzzer runs because the gsid.mapped_images.* properties
are not destroyed in SoftReset.

Test: libsnapshot_fuzzer_test then reboot, device can come up
Fixes: 156689792
Bug: 156380383
Change-Id: I7a198312f63b4b17d8ea96c7df2dd112a910d004
parent 8cef7c7d
Loading
Loading
Loading
Loading
+18 −12
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <cutils/properties.h>
#include <fs_mgr.h>
#include <libsnapshot/auto_device.h>
#include <libsnapshot/snapshot.h>
@@ -165,14 +164,6 @@ void InsertProperty(const char* key, const char* /*name*/, void* cookie) {
    reinterpret_cast<PropertyList*>(cookie)->insert(key);
}

void CheckUnsetGsidProps() {
    PropertyList list;
    property_list(&InsertProperty, reinterpret_cast<void*>(&list));
    for (const auto& key : list) {
        SetProperty(key, "");
    }
}

// Attempt to delete all devices that is based on dev_name, including itself.
void CheckDeleteDeviceMapperTree(const std::string& dev_name, bool known_allow_delete = false,
                                 uint64_t depth = 100) {
@@ -344,7 +335,6 @@ class AutoMemBasedDir : public AutoDevice {
};

SnapshotFuzzEnv::SnapshotFuzzEnv() {
    CheckUnsetGsidProps();
    CheckCleanupDeviceMapperDevices();
    CheckDetachLoopDevices();
    CheckUmountAll();
@@ -368,7 +358,6 @@ SnapshotFuzzEnv::SnapshotFuzzEnv() {
}

SnapshotFuzzEnv::~SnapshotFuzzEnv() {
    CheckUnsetGsidProps();
    CheckCleanupDeviceMapperDevices();
    mounted_data_ = nullptr;
    auto_delete_data_mount_point_ = nullptr;
@@ -396,7 +385,7 @@ std::unique_ptr<IImageManager> SnapshotFuzzEnv::CheckCreateFakeImageManager(
        const std::string& metadata_dir, const std::string& data_dir) {
    PCHECK(Mkdir(metadata_dir));
    PCHECK(Mkdir(data_dir));
    return ImageManager::Open(metadata_dir, data_dir);
    return SnapshotFuzzImageManager::Open(metadata_dir, data_dir);
}

// Helper to create a loop device for a file.
@@ -507,4 +496,21 @@ std::unique_ptr<AutoDevice> SnapshotFuzzEnv::CheckMountFormatData(const std::str
    return std::make_unique<AutoUnmount>(mount_point);
}

SnapshotFuzzImageManager::~SnapshotFuzzImageManager() {
    // Remove relevant gsid.mapped_images.* props.
    for (const auto& name : mapped_) {
        CHECK(UnmapImageIfExists(name)) << "Cannot unmap " << name;
    }
}

bool SnapshotFuzzImageManager::MapImageDevice(const std::string& name,
                                              const std::chrono::milliseconds& timeout_ms,
                                              std::string* path) {
    if (impl_->MapImageDevice(name, timeout_ms, path)) {
        mapped_.insert(name);
        return true;
    }
    return false;
}

}  // namespace android::snapshot
+66 −0
Original line number Diff line number Diff line
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#include <memory>
#include <set>
#include <string>

#include <android-base/file.h>
@@ -134,4 +136,68 @@ class SnapshotFuzzDeviceInfo : public ISnapshotManager::IDeviceInfo {
    bool CurrentSlotIsA() const { return data_->slot_suffix_is_a() != switched_slot_; }
};

// A spy class on ImageManager implementation. Upon destruction, unmaps all images
// map through this object.
class SnapshotFuzzImageManager : public android::fiemap::IImageManager {
  public:
    static std::unique_ptr<SnapshotFuzzImageManager> Open(const std::string& metadata_dir,
                                                          const std::string& data_dir) {
        auto impl = android::fiemap::ImageManager::Open(metadata_dir, data_dir);
        if (impl == nullptr) return nullptr;
        return std::unique_ptr<SnapshotFuzzImageManager>(
                new SnapshotFuzzImageManager(std::move(impl)));
    }

    ~SnapshotFuzzImageManager();

    // Spied APIs.
    bool MapImageDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms,
                        std::string* path) override;

    // Other functions call through.
    android::fiemap::FiemapStatus CreateBackingImage(
            const std::string& name, uint64_t size, int flags,
            std::function<bool(uint64_t, uint64_t)>&& on_progress) override {
        return impl_->CreateBackingImage(name, size, flags, std::move(on_progress));
    }
    bool DeleteBackingImage(const std::string& name) override {
        return impl_->DeleteBackingImage(name);
    }
    bool UnmapImageDevice(const std::string& name) override {
        return impl_->UnmapImageDevice(name);
    }
    bool BackingImageExists(const std::string& name) override {
        return impl_->BackingImageExists(name);
    }
    bool IsImageMapped(const std::string& name) override { return impl_->IsImageMapped(name); }
    bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name,
                                  std::string* dev) override {
        return impl_->MapImageWithDeviceMapper(opener, name, dev);
    }
    bool GetMappedImageDevice(const std::string& name, std::string* device) override {
        return impl_->GetMappedImageDevice(name, device);
    }
    bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) override {
        return impl_->MapAllImages(init);
    }
    bool DisableImage(const std::string& name) override { return impl_->DisableImage(name); }
    bool RemoveDisabledImages() override { return impl_->RemoveDisabledImages(); }
    std::vector<std::string> GetAllBackingImages() override { return impl_->GetAllBackingImages(); }
    android::fiemap::FiemapStatus ZeroFillNewImage(const std::string& name,
                                                   uint64_t bytes) override {
        return impl_->ZeroFillNewImage(name, bytes);
    }
    bool RemoveAllImages() override { return impl_->RemoveAllImages(); }
    bool UnmapImageIfExists(const std::string& name) override {
        return impl_->UnmapImageIfExists(name);
    }

  private:
    std::unique_ptr<android::fiemap::IImageManager> impl_;
    std::set<std::string> mapped_;

    SnapshotFuzzImageManager(std::unique_ptr<android::fiemap::IImageManager>&& impl)
        : impl_(std::move(impl)) {}
};

}  // namespace android::snapshot