Skip to content

Commit

Permalink
uefi_fv: Minor fixes
Browse files Browse the repository at this point in the history
 - Add additional error handling for LZMA-compressed GUID-defined
   sections
 - Parse UEFI firmware volume extended headers
  • Loading branch information
al3xtjames committed Jul 22, 2019
1 parent e169fe4 commit c81a34e
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 21 deletions.
19 changes: 13 additions & 6 deletions src/main/java/firmware/uefi_fv/FFSGUIDDefinedSection.java
Expand Up @@ -100,13 +100,20 @@ public FFSGUIDDefinedSection(BinaryReader reader, UEFIFirmwareVolumeFileSystem f
reader.getByteProvider().getInputStream(reader.getPointerIndex()),
length());

LZMACompressorInputStream inputStream = new LZMACompressorInputStream(boundedStream);
uncompressedData = inputStream.readAllBytes();
try {
LZMACompressorInputStream inputStream = new LZMACompressorInputStream(boundedStream);
uncompressedData = inputStream.readAllBytes();

// Parse the uncompressed section.
BinaryReader sectionReader = new BinaryReader(
new ByteArrayProvider(uncompressedData), true);
parseNestedSections(sectionReader, uncompressedData.length, fs, fileImpl);
// Parse the uncompressed section.
BinaryReader sectionReader = new BinaryReader(
new ByteArrayProvider(uncompressedData), true);
parseNestedSections(sectionReader, uncompressedData.length, fs, fileImpl);
} catch (IOException e) {
Msg.error(this, "Failed to extract LZMA compressed section: " +
e.getMessage());
reader.setPointerIndex(baseIndex + getTotalLength());
return;
}
} else {
// Parse the data in the current GUID-defined section.
parseNestedSections(reader, length(), fs, fileImpl);
Expand Down
44 changes: 29 additions & 15 deletions src/main/java/firmware/uefi_fv/UEFIFirmwareVolumeHeader.java
Expand Up @@ -57,6 +57,17 @@
* | u32 | 4 | Block Size |
* +------+------+------------------+
*
* The Extended Header Offset field is relative to the start of firmware volume header; it has the
* following structure:
*
* UEFI Firmware Volume Extended Header
* +------------+------+----------------------+
* | Type | Size | Description |
* +------------+------+----------------------+
* | efi_guid_t | 16 | Firmware Volume Name |
* | u32 | 4 | Extended Header Size |
* +------------+------+----------------------+
*
* Each firmware volume contains a number of UEFI Firmware File System (FFS) files, which may be
* aligned depending on the bits set in the Attributes field of the UEFI Firmware Volume header.
* See UFSIFFSFile and UEFIFFSv3File for information regarding the FFS file header fields.
Expand All @@ -73,6 +84,10 @@ public class UEFIFirmwareVolumeHeader implements UEFIFile {
private short extendedHeaderOffset;
private byte revision;

// Extended header fields
private UUID fvName;
private int extendedHeaderSize;

private long baseIndex;

/**
Expand All @@ -90,7 +105,7 @@ public UEFIFirmwareVolumeHeader(BinaryReader reader, UEFIFirmwareVolumeFileSyste

fileSystemGuid = UUIDUtils.fromBinaryReader(reader);
size = reader.readNextLong();
if (size <= UEFIFirmwareVolumeConstants.UEFI_FV_HEADER_SIZE) {
if (size < UEFIFirmwareVolumeConstants.UEFI_FV_HEADER_SIZE) {
throw new IOException("Not a valid UEFI FV header");
}

Expand All @@ -112,11 +127,11 @@ public UEFIFirmwareVolumeHeader(BinaryReader reader, UEFIFirmwareVolumeFileSyste
// Skip the FvBlockMap field.
reader.setPointerIndex(reader.getPointerIndex() + 16);

// Read the extended header fields (if present).
if (revision == 2 && extendedHeaderOffset > 0) {
// The extended header structure consists of a EFI GUID followed by the size of the
// header (stored as u32).
reader.setPointerIndex(baseIndex + extendedHeaderOffset + 16);
int extendedHeaderSize = reader.readNextInt();
reader.setPointerIndex(baseIndex + extendedHeaderOffset);
fvName = UUIDUtils.fromBinaryReader(reader);
extendedHeaderSize = reader.readNextInt();
reader.setPointerIndex(baseIndex + extendedHeaderOffset + extendedHeaderSize);
}

Expand Down Expand Up @@ -155,7 +170,6 @@ public UEFIFirmwareVolumeHeader(BinaryReader reader, UEFIFirmwareVolumeFileSyste
reader.align(8);
}

long originalIndex = reader.getPointerIndex();
try {
UEFIFFSFile file = new UEFIFFSFile(reader, fs, fileImpl);
} catch (IOException e) {
Expand All @@ -168,21 +182,16 @@ public UEFIFirmwareVolumeHeader(BinaryReader reader, UEFIFirmwareVolumeFileSyste
reader.setPointerIndex(baseIndex + size);
}

/**
* Returns the file system GUID for the current firmware volume.
*
* @return the file system GUID for the current firmware volume
*/
public UUID getGUID() {
return fileSystemGuid;
}

/**
* Returns the name of the current firmware volume.
*
* @return the name of the current firmware volume
*/
public String getName() {
if (fvName != null) {
return UUIDUtils.getName(fvName);
}

return UUIDUtils.getName(fileSystemGuid);
}

Expand All @@ -209,6 +218,11 @@ public String toString() {
formatter.format("Firmware volume attributes: 0x%X\n", attributes);
formatter.format("Firmware volume header size: 0x%X\n", headerSize);
formatter.format("Firmware volume revision: %d", revision);
if (revision == 2 && extendedHeaderOffset > 0) {
formatter.format("\nFirmware volume name GUID: %s\n", fvName.toString());
formatter.format("Firmware volume extended header size: 0x%X", extendedHeaderSize);
}

return formatter.toString();
}
}

0 comments on commit c81a34e

Please sign in to comment.