pe-binary: wrap remaining LE fields with byte-swap macros
Follow-up to 02cab70acf. pe_hash(),
section_offset_cmp() and uki_hash() still had a bunch of raw accesses
to LE fields (e_lfanew, SizeOfHeaders, PointerToRawData, SizeOfRawData,
VirtualSize, certificate_table->Size) without le32toh(), so they'd
produce garbage on big-endian.
Also wrap VirtualSize in bootspec.c for consistency.
This commit is contained in:
committed by
Yu Watanabe
parent
81cef494a6
commit
b3a2444ba5
@@ -1020,7 +1020,7 @@ static int pe_find_uki_sections(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Permit "masking" of sections in the base profile */
|
/* Permit "masking" of sections in the base profile */
|
||||||
if (found->VirtualSize == 0)
|
if (le32toh(found->VirtualSize) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
r = pe_read_section_data(fd, found, PE_SECTION_SIZE_MAX, (void**) t->data, /* ret_size= */ NULL);
|
r = pe_read_section_data(fd, found, PE_SECTION_SIZE_MAX, (void**) t->data, /* ret_size= */ NULL);
|
||||||
|
|||||||
+11
-11
@@ -336,7 +336,7 @@ static int hash_file(int fd, EVP_MD_CTX *md_ctx, uint64_t offset, uint64_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int section_offset_cmp(const IMAGE_SECTION_HEADER *a, const IMAGE_SECTION_HEADER *b) {
|
static int section_offset_cmp(const IMAGE_SECTION_HEADER *a, const IMAGE_SECTION_HEADER *b) {
|
||||||
return CMP(ASSERT_PTR(a)->PointerToRawData, ASSERT_PTR(b)->PointerToRawData);
|
return CMP(le32toh(ASSERT_PTR(a)->PointerToRawData), le32toh(ASSERT_PTR(b)->PointerToRawData));
|
||||||
}
|
}
|
||||||
|
|
||||||
int pe_hash(int fd,
|
int pe_hash(int fd,
|
||||||
@@ -384,7 +384,7 @@ int pe_hash(int fd,
|
|||||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to allocate message digest.");
|
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to allocate message digest.");
|
||||||
|
|
||||||
/* Everything from beginning of file to CheckSum field in PE header */
|
/* Everything from beginning of file to CheckSum field in PE header */
|
||||||
p = (uint64_t) dos_header->e_lfanew +
|
p = (uint64_t) le32toh(dos_header->e_lfanew) +
|
||||||
offsetof(PeHeader, optional.CheckSum);
|
offsetof(PeHeader, optional.CheckSum);
|
||||||
r = hash_file(fd, mdctx, 0, p);
|
r = hash_file(fd, mdctx, 0, p);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -392,7 +392,7 @@ int pe_hash(int fd,
|
|||||||
p += sizeof(le32_t);
|
p += sizeof(le32_t);
|
||||||
|
|
||||||
/* Everything between the CheckSum field and the Image Data Directory Entry for the Certification Table */
|
/* Everything between the CheckSum field and the Image Data Directory Entry for the Certification Table */
|
||||||
q = (uint64_t) dos_header->e_lfanew +
|
q = (uint64_t) le32toh(dos_header->e_lfanew) +
|
||||||
PE_HEADER_OPTIONAL_FIELD_OFFSET(pe_header, DataDirectory[IMAGE_DATA_DIRECTORY_INDEX_CERTIFICATION_TABLE]);
|
PE_HEADER_OPTIONAL_FIELD_OFFSET(pe_header, DataDirectory[IMAGE_DATA_DIRECTORY_INDEX_CERTIFICATION_TABLE]);
|
||||||
r = hash_file(fd, mdctx, p, q - p);
|
r = hash_file(fd, mdctx, p, q - p);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -400,7 +400,7 @@ int pe_hash(int fd,
|
|||||||
q += sizeof(IMAGE_DATA_DIRECTORY);
|
q += sizeof(IMAGE_DATA_DIRECTORY);
|
||||||
|
|
||||||
/* The rest of the header + the section table */
|
/* The rest of the header + the section table */
|
||||||
p = pe_header->optional.SizeOfHeaders;
|
p = le32toh(pe_header->optional.SizeOfHeaders);
|
||||||
if (p < q)
|
if (p < q)
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "SizeOfHeaders too short.");
|
return log_debug_errno(SYNTHETIC_ERRNO(EBADMSG), "SizeOfHeaders too short.");
|
||||||
r = hash_file(fd, mdctx, q, p - q);
|
r = hash_file(fd, mdctx, q, p - q);
|
||||||
@@ -411,19 +411,19 @@ int pe_hash(int fd,
|
|||||||
typesafe_qsort(sections, le16toh(pe_header->pe.NumberOfSections), section_offset_cmp);
|
typesafe_qsort(sections, le16toh(pe_header->pe.NumberOfSections), section_offset_cmp);
|
||||||
|
|
||||||
FOREACH_ARRAY(section, sections, le16toh(pe_header->pe.NumberOfSections)) {
|
FOREACH_ARRAY(section, sections, le16toh(pe_header->pe.NumberOfSections)) {
|
||||||
r = hash_file(fd, mdctx, section->PointerToRawData, section->SizeOfRawData);
|
r = hash_file(fd, mdctx, le32toh(section->PointerToRawData), le32toh(section->SizeOfRawData));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
p += section->SizeOfRawData;
|
p += le32toh(section->SizeOfRawData);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uint64_t) st.st_size > p) {
|
if ((uint64_t) st.st_size > p) {
|
||||||
|
|
||||||
if (st.st_size - p < certificate_table->Size)
|
if ((uint64_t) st.st_size - p < le32toh(certificate_table->Size))
|
||||||
return log_debug_errno(errno, "No space for certificate table, refusing.");
|
return log_debug_errno(errno, "No space for certificate table, refusing.");
|
||||||
|
|
||||||
r = hash_file(fd, mdctx, p, st.st_size - p - certificate_table->Size);
|
r = hash_file(fd, mdctx, p, st.st_size - p - le32toh(certificate_table->Size));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@@ -560,13 +560,13 @@ int uki_hash(int fd,
|
|||||||
if (EVP_DigestInit_ex(mdctx, md, NULL) != 1)
|
if (EVP_DigestInit_ex(mdctx, md, NULL) != 1)
|
||||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to allocate message digest.");
|
return log_debug_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to allocate message digest.");
|
||||||
|
|
||||||
r = hash_file(fd, mdctx, section->PointerToRawData, MIN(section->VirtualSize, section->SizeOfRawData));
|
r = hash_file(fd, mdctx, le32toh(section->PointerToRawData), MIN(le32toh(section->VirtualSize), le32toh(section->SizeOfRawData)));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (section->SizeOfRawData < section->VirtualSize) {
|
if (le32toh(section->SizeOfRawData) < le32toh(section->VirtualSize)) {
|
||||||
uint8_t zeroes[1024] = {};
|
uint8_t zeroes[1024] = {};
|
||||||
size_t remaining = section->VirtualSize - section->SizeOfRawData;
|
size_t remaining = le32toh(section->VirtualSize) - le32toh(section->SizeOfRawData);
|
||||||
|
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
size_t sz = MIN(sizeof(zeroes), remaining);
|
size_t sz = MIN(sizeof(zeroes), remaining);
|
||||||
|
|||||||
Reference in New Issue
Block a user