igvmfilegen: read IGVM from vmfirmwareigvm resource DLL in dump/dump-corim - #4059
Open
mingweishih wants to merge 2 commits into
Open
igvmfilegen: read IGVM from vmfirmwareigvm resource DLL in dump/dump-corim#4059mingweishih wants to merge 2 commits into
mingweishih wants to merge 2 commits into
Conversation
…corim The production OpenHCL IGVM is shipped encapsulated in a Windows resource-only DLL (vmfirmwareigvm.dll / vmfirmwarecvm.dll), where the IGVM payload is stored as a custom VMFW resource (id 1). 'dump' and 'dump-corim' previously only accepted a raw IGVM file, so there was no way to check the CoRIM embedded in a shipped firmware DLL. Add a firmware_dll module that detects a PE input (MZ signature) and extracts the embedded VMFW resource via the object crate, and route 'dump'/'dump-corim' through it. A raw IGVM file is passed through unchanged. This lets 'igvmfilegen dump-corim --filepath vmfirmwarecvm.dll' report the CoRIM documents/signatures directly from the packaged DLL.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR enhances igvmfilegen so dump and dump-corim can accept either a raw IGVM file or a shipped OpenHCL firmware resource DLL (vmfirmwareigvm.dll / vmfirmwarecvm.dll) by detecting PE inputs and extracting the embedded VMFW resource payload.
Changes:
- Added a new
firmware_dllmodule to transparently extract an IGVM image from a PE resource DLL. - Routed
dumpanddump-coriminput loading through the new extraction path. - Updated CLI help text and added the
objectcrate dependency for PE/resource parsing.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| vm/loader/igvmfilegen/src/main.rs | Routes dump / dump-corim through firmware_dll::read_igvm_image and updates CLI documentation. |
| vm/loader/igvmfilegen/src/firmware_dll.rs | Implements PE detection + VMFW resource extraction and adds basic unit tests for UTF-16 name matching. |
| vm/loader/igvmfilegen/Cargo.toml | Adds object dependency with PE reading support. |
| Cargo.lock | Locks the new object dependency version. |
Comments suppressed due to low confidence (2)
vm/loader/igvmfilegen/src/main.rs:318
Dumpcurrently uses.expect(...)when reading the IGVM fixed header / parsing the IGVM, which will panic on malformed input.dump-corimalready returns a structuredanyhowerror for the same condition; makingdumpconsistent avoids crashes and gives users a clearer failure mode.
let image = firmware_dll::read_igvm_image(&file_path)?;
let fixed_header = IGVM_FIXED_HEADER::read_from_prefix(image.as_bytes())
.expect("Invalid fixed header")
.0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759)
vm/loader/igvmfilegen/src/firmware_dll.rs:82
- The resource is documented as being stored under numeric id
1, but the extraction currently just takes the first id entry. If the DLL ever contains multipleVMFWentries (or ordering changes), this can silently extract the wrong payload. Prefer selecting id=1 explicitly.
let id_entry = id_table
.entries
.first()
.context("VMFW resource type has no entries")?;
Comment on lines
+29
to
+33
| pub fn read_igvm_image(path: &Path) -> anyhow::Result<Vec<u8>> { | ||
| let bytes = fs_err::read(path).context("reading input file")?; | ||
| if bytes.starts_with(b"MZ") { | ||
| extract_vmfw_resource(&bytes).with_context(|| { | ||
| format!( |
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
vm/loader/igvmfilegen/src/main.rs:319
Dumpstill usesexpect(...)when parsing the fixed header / IGVM binary, which will panic (crash) on malformed input (including malformed resource DLLs). This is inconsistent withdump_corim_headers, which returns a structuredanyhow::Resulterror instead of panicking.
let image = firmware_dll::read_igvm_image(&file_path)?;
let fixed_header = IGVM_FIXED_HEADER::read_from_prefix(image.as_bytes())
.expect("Invalid fixed header")
.0; // TODO: zerocopy: use-rest-of-range (https://github.com/microsoft/openvmm/issues/759)
let igvm_data = IgvmFile::new_from_binary(&image, None).expect("should be valid");
vm/loader/igvmfilegen/src/firmware_dll.rs:82
- The VMFW resource is documented as id
1(1 VMFW ...inresources.rc), but the extractor currently takes the first ID entry under the VMFW type. If additional VMFW resources are ever added (or ordering differs), this can silently extract the wrong payload.
let id_entry = id_table
.entries
.first()
.context("VMFW resource type has no entries")?;
vm/loader/igvmfilegen/src/firmware_dll.rs:135
- Other unit tests in this crate import
use test_with_tracing::test;so#[test]initializes tracing (e.g.corim_signature/envelope.rs:234,snp_id_block.rs:521). These new tests use the plain built-in#[test], so they won't capture tracing output consistently with the rest of the crate.
#[cfg(test)]
mod tests {
use super::utf16le_eq;
fn utf16le(s: &str) -> Vec<u8> {
s.encode_utf16().flat_map(u16::to_le_bytes).collect()
}
#[test]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The production OpenHCL IGVM is shipped encapsulated in a Windows resource-only DLL (
vmfirmwareigvm.dll/vmfirmwarecvm.dll), where the IGVM payload is stored as a customVMFWresource (id 1) — see1 VMFW <igvm>inopenhcl/vmfirmwareigvm_dll/resources.rc. Thedumpanddump-corimsubcommands only accepted a raw IGVM file, so there was no way to check the CoRIM embedded in a shipped firmware DLL without first extracting the IGVM by hand.Change
firmware_dllmodule that detects a PE input (MZsignature) and extracts the embeddedVMFWresource using theobjectcrate (safe, cross-platform — no Win32 APIs, keeps#![forbid(unsafe_code)]).dumpanddump-corimthrough it. A raw IGVM file is passed through unchanged; a resource DLL has its IGVM extracted transparently.This lets you check the packaged firmware directly:
Validation
Ran against a real signed
vmfirmwarecvm.dll:cargo clippy -p igvmfilegen --all-targets— cleancargo doc --no-deps -p igvmfilegen— cleancargo test -p igvmfilegen— 47 passed (incl. newfirmware_dlltests)dumpon the same DLL prints the extracted IGVM fixed header (magicIGVM), confirming a valid raw IGVM is recovered.