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

Commit 1eb3ea37 authored by David Anderson's avatar David Anderson
Browse files

liblp: Refactor ParseMetadata to read from non-descriptors.

This is in preparation for "fastboot flash super", where we want to
verify the validity of a super image before writing it. To do so, we
need to parse the image from the download buffer, and it is useful to do
this from memory rather than a file descriptor.

Bug: 78793464
Test: liblp_test gtest
Change-Id: I7fb1ef4fdf2e8f1d93aea38f75626157fcb4bfc1
parent f1222908
Loading
Loading
Loading
Loading
+27 −3
Original line number Diff line number Diff line
@@ -30,6 +30,24 @@
namespace android {
namespace fs_mgr {

// Helper class for reading descriptors and memory buffers in the same manner.
class Reader {
  public:
    virtual ~Reader(){};
    virtual bool ReadFully(void* buffer, size_t length) = 0;
};

class FileReader final : public Reader {
  public:
    explicit FileReader(int fd) : fd_(fd) {}
    bool ReadFully(void* buffer, size_t length) override {
        return android::base::ReadFully(fd_, buffer, length);
    }

  private:
    int fd_;
};

// Parse an LpMetadataGeometry from a buffer. The buffer must be at least
// LP_METADATA_GEOMETRY_SIZE bytes in size.
static bool ParseGeometry(const void* buffer, LpMetadataGeometry* geometry) {
@@ -171,10 +189,11 @@ static bool ValidateMetadataHeader(const LpMetadataHeader& header) {

// Parse and validate all metadata at the current position in the given file
// descriptor.
std::unique_ptr<LpMetadata> ParseMetadata(const LpMetadataGeometry& geometry, int fd) {
static std::unique_ptr<LpMetadata> ParseMetadata(const LpMetadataGeometry& geometry,
                                                 Reader* reader) {
    // First read and validate the header.
    std::unique_ptr<LpMetadata> metadata = std::make_unique<LpMetadata>();
    if (!android::base::ReadFully(fd, &metadata->header, sizeof(metadata->header))) {
    if (!reader->ReadFully(&metadata->header, sizeof(metadata->header))) {
        PERROR << __PRETTY_FUNCTION__ << "read " << sizeof(metadata->header) << "bytes failed";
        return nullptr;
    }
@@ -192,7 +211,7 @@ std::unique_ptr<LpMetadata> ParseMetadata(const LpMetadataGeometry& geometry, in
        LERROR << "Out of memory reading logical partition tables.";
        return nullptr;
    }
    if (!android::base::ReadFully(fd, buffer.get(), header.tables_size)) {
    if (!reader->ReadFully(buffer.get(), header.tables_size)) {
        PERROR << __PRETTY_FUNCTION__ << "read " << header.tables_size << "bytes failed";
        return nullptr;
    }
@@ -235,6 +254,11 @@ std::unique_ptr<LpMetadata> ParseMetadata(const LpMetadataGeometry& geometry, in
    return metadata;
}

std::unique_ptr<LpMetadata> ParseMetadata(const LpMetadataGeometry& geometry, int fd) {
    FileReader reader(fd);
    return ParseMetadata(geometry, &reader);
}

std::unique_ptr<LpMetadata> ReadPrimaryMetadata(int fd, const LpMetadataGeometry& geometry,
                                                uint32_t slot_number) {
    int64_t offset = GetPrimaryMetadataOffset(geometry, slot_number);