Merge "liblp: Force more sizes to be a multiple of the sector size."

This commit is contained in:
Treehugger Robot 2018-07-16 17:08:49 +00:00 committed by Gerrit Code Review
commit 474990089a
4 changed files with 15 additions and 20 deletions

View file

@ -200,6 +200,11 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata
metadata_max_size = AlignTo(metadata_max_size, LP_SECTOR_SIZE);
// Check that device properties are sane.
device_info_ = device_info;
if (device_info_.size % LP_SECTOR_SIZE != 0) {
LERROR << "Block device size must be a multiple of 512.";
return false;
}
if (device_info_.alignment_offset % LP_SECTOR_SIZE != 0) {
LERROR << "Alignment offset is not sector-aligned.";
return false;
@ -212,7 +217,6 @@ bool MetadataBuilder::Init(const BlockDeviceInfo& device_info, uint32_t metadata
LERROR << "Partition alignment offset is greater than its alignment.";
return false;
}
device_info_ = device_info;
// We reserve a geometry block (4KB) plus space for each copy of the
// maximum size of a metadata blob. Then, we double that space since

View file

@ -106,19 +106,9 @@ TEST(liblp, DiskAlignment) {
static const uint32_t kMetadataSize = 1024;
static const uint32_t kMetadataSlots = 2;
// If the disk size is not aligned to 512 bytes, make sure it still leaves
// space at the end for backup metadata, and that it doesn't overlap with
// the space for logical partitions.
unique_ptr<MetadataBuilder> builder =
MetadataBuilder::New(kDiskSize, kMetadataSize, kMetadataSlots);
unique_ptr<LpMetadata> exported = builder->Export();
ASSERT_NE(exported, nullptr);
static const size_t kMetadataSpace =
(kMetadataSize * kMetadataSlots) + LP_METADATA_GEOMETRY_SIZE;
uint64_t space_at_end =
kDiskSize - (exported->geometry.last_logical_sector + 1) * LP_SECTOR_SIZE;
EXPECT_GE(space_at_end, kMetadataSpace);
ASSERT_EQ(builder, nullptr);
}
TEST(liblp, MetadataAlignment) {
@ -148,15 +138,10 @@ TEST(liblp, InternalAlignment) {
EXPECT_EQ(exported->geometry.first_logical_sector, 1472);
EXPECT_EQ(exported->geometry.last_logical_sector, 2035);
// Test only an alignment offset (which should simply bump up the first
// logical sector).
// Alignment offset without alignment doesn't mean anything.
device_info.alignment = 0;
builder = MetadataBuilder::New(device_info, 1024, 2);
ASSERT_NE(builder, nullptr);
exported = builder->Export();
ASSERT_NE(exported, nullptr);
EXPECT_EQ(exported->geometry.first_logical_sector, 1484);
EXPECT_EQ(exported->geometry.last_logical_sector, 2035);
ASSERT_EQ(builder, nullptr);
// Test a small alignment with an alignment offset.
device_info.alignment = 12 * 1024;

View file

@ -86,7 +86,9 @@ typedef struct LpMetadataGeometry {
/* 8: SHA256 checksum of this struct, with this field set to 0. */
uint8_t checksum[32];
/* 40: Maximum amount of space a single copy of the metadata can use. */
/* 40: Maximum amount of space a single copy of the metadata can use. This
* must be a multiple of LP_SECTOR_SIZE.
*/
uint32_t metadata_max_size;
/* 44: Number of copies of the metadata to keep. For A/B devices, this

View file

@ -68,6 +68,10 @@ static bool ParseGeometry(const void* buffer, LpMetadataGeometry* geometry) {
LERROR << "Logical partition metadata has invalid slot count.";
return false;
}
if (geometry->metadata_max_size % LP_SECTOR_SIZE != 0) {
LERROR << "Metadata max size is not sector-aligned.";
return false;
}
// Check that the metadata area and logical partition areas don't overlap.
int64_t end_of_metadata =