diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp index 07f9d66d0..8d08689e2 100644 --- a/fs_mgr/liblp/builder.cpp +++ b/fs_mgr/liblp/builder.cpp @@ -267,6 +267,11 @@ void MetadataBuilder::ImportExtents(Partition* dest, const LpMetadata& metadata, } static bool VerifyDeviceProperties(const BlockDeviceInfo& device_info) { + if (device_info.logical_block_size == 0) { + LERROR << "Block device " << device_info.partition_name + << " logical block size must not be zero."; + return false; + } if (device_info.logical_block_size % LP_SECTOR_SIZE != 0) { LERROR << "Block device " << device_info.partition_name << " logical block size must be a multiple of 512."; @@ -333,7 +338,7 @@ bool MetadataBuilder::Init(const std::vector& block_devices, out.alignment = device_info.alignment; out.alignment_offset = device_info.alignment_offset; out.size = device_info.size; - if (device_info.partition_name.size() >= sizeof(out.partition_name)) { + if (device_info.partition_name.size() > sizeof(out.partition_name)) { LERROR << "Partition name " << device_info.partition_name << " exceeds maximum length."; return false; } diff --git a/fs_mgr/liblp/include/liblp/metadata_format.h b/fs_mgr/liblp/include/liblp/metadata_format.h index 9c5ec5c93..8934aaff2 100644 --- a/fs_mgr/liblp/include/liblp/metadata_format.h +++ b/fs_mgr/liblp/include/liblp/metadata_format.h @@ -127,7 +127,7 @@ typedef struct LpMetadataGeometry { * num_entries, and the result must not overflow a 32-bit signed integer. */ typedef struct LpMetadataTableDescriptor { - /* 0: Location of the table, relative to the metadata header. */ + /* 0: Location of the table, relative to end of the metadata header. */ uint32_t offset; /* 4: Number of entries in the table. */ uint32_t num_entries; @@ -272,7 +272,7 @@ typedef struct LpMetadataPartitionGroup { /* 40: Maximum size in bytes. If 0, the group has no maximum size. */ uint64_t maximum_size; -} LpMetadataPartitionGroup; +} __attribute__((packed)) LpMetadataPartitionGroup; /* This flag is only intended to be used with super_empty.img and super.img on * retrofit devices. If set, the group needs a slot suffix to be interpreted @@ -323,7 +323,7 @@ typedef struct LpMetadataBlockDevice { /* 60: Flags (see LP_BLOCK_DEVICE_* flags below). */ uint32_t flags; -} LpMetadataBlockDevice; +} __attribute__((packed)) LpMetadataBlockDevice; /* This flag is only intended to be used with super_empty.img and super.img on * retrofit devices. On these devices there are A and B super partitions, and diff --git a/fs_mgr/liblp/reader.cpp b/fs_mgr/liblp/reader.cpp index 24c6b2c31..dcee6d2d8 100644 --- a/fs_mgr/liblp/reader.cpp +++ b/fs_mgr/liblp/reader.cpp @@ -256,6 +256,10 @@ static std::unique_ptr ParseMetadata(const LpMetadataGeometry& geome LERROR << "Logical partition has invalid attribute set."; return nullptr; } + if (partition.first_extent_index + partition.num_extents < partition.first_extent_index) { + LERROR << "Logical partition first_extent_index + num_extents overflowed."; + return nullptr; + } if (partition.first_extent_index + partition.num_extents > header.extents.num_entries) { LERROR << "Logical partition has invalid extent list."; return nullptr; diff --git a/fs_mgr/liblp/writer.cpp b/fs_mgr/liblp/writer.cpp index 454258b75..0ab0d8cf6 100644 --- a/fs_mgr/liblp/writer.cpp +++ b/fs_mgr/liblp/writer.cpp @@ -367,11 +367,11 @@ bool UpdatePartitionTable(const IPartitionOpener& opener, const std::string& sup // safety. std::string old_blob; if (!ValidateAndSerializeMetadata(opener, *backup.get(), slot_suffix, &old_blob)) { - LERROR << "Error serializing primary metadata to repair corrupted backup"; + LERROR << "Error serializing backup metadata to repair corrupted primary"; return false; } if (!WritePrimaryMetadata(fd, metadata, slot_number, old_blob, writer)) { - LERROR << "Error writing primary metadata to repair corrupted backup"; + LERROR << "Error writing backup metadata to repair corrupted primary"; return false; } }