Skip to content

igvmfilegen: read IGVM from vmfirmwareigvm resource DLL in dump/dump-corim - #4059

Open
mingweishih wants to merge 2 commits into
microsoft:mainfrom
mingweishih:igvmfilegen_dump_corim_from_dll
Open

igvmfilegen: read IGVM from vmfirmwareigvm resource DLL in dump/dump-corim#4059
mingweishih wants to merge 2 commits into
microsoft:mainfrom
mingweishih:igvmfilegen_dump_corim_from_dll

Conversation

@mingweishih

Copy link
Copy Markdown
Contributor

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 custom VMFW resource (id 1) — see 1 VMFW <igvm> in openhcl/vmfirmwareigvm_dll/resources.rc. The dump and dump-corim subcommands 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

  • Add a firmware_dll module that detects a PE input (MZ signature) and extracts the embedded VMFW resource using the object crate (safe, cross-platform — no Win32 APIs, keeps #![forbid(unsafe_code)]).
  • Route dump and dump-corim through 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:

igvmfilegen dump-corim --filepath vmfirmwarecvm.dll

Validation

Ran against a real signed vmfirmwarecvm.dll:

Supported Platforms:
  SEV_SNP -> compatibility_mask 0x1
  TDX -> compatibility_mask 0x2
  VSM_ISOLATION -> compatibility_mask 0x4

CoRIM Document (snp): ... 330 bytes
CoRIM Document (vbs): ... 304 bytes
CoRIM Document (tdx): ... 310 bytes
CoRIM Signature (tdx): ... 6353 bytes
Summary: 3 document header(s), 1 signature header(s)
  • cargo clippy -p igvmfilegen --all-targets — clean
  • cargo doc --no-deps -p igvmfilegen — clean
  • cargo test -p igvmfilegen — 47 passed (incl. new firmware_dll tests)
  • dump on the same DLL prints the extracted IGVM fixed header (magic IGVM), confirming a valid raw IGVM is recovered.

…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.
Copilot AI review requested due to automatic review settings July 28, 2026 17:55
@mingweishih
mingweishih requested a review from a team as a code owner July 28, 2026 17:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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_dll module to transparently extract an IGVM image from a PE resource DLL.
  • Routed dump and dump-corim input loading through the new extraction path.
  • Updated CLI help text and added the object crate 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

  • Dump currently uses .expect(...) when reading the IGVM fixed header / parsing the IGVM, which will panic on malformed input. dump-corim already returns a structured anyhow error for the same condition; making dump consistent 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 multiple VMFW entries (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!(
@mingweishih mingweishih reopened this Jul 28, 2026
Copilot AI review requested due to automatic review settings July 28, 2026 18:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

  • Dump still uses expect(...) when parsing the fixed header / IGVM binary, which will panic (crash) on malformed input (including malformed resource DLLs). This is inconsistent with dump_corim_headers, which returns a structured anyhow::Result error 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 ... in resources.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]

@github-actions

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants