Thanks to visit codestin.com
Credit goes to github.com

Skip to content

block: qcow: Validate QCOW2 v3 incompatible feature bits - #7612

Merged
likebreath merged 2 commits into
cloud-hypervisor:mainfrom
weltling:qcow-v3-feature-name-table
Jan 23, 2026
Merged

likebreath merged 2 commits into
cloud-hypervisor:mainfrom
weltling:qcow-v3-feature-name-table

Conversation

@weltling

@weltling weltling commented Jan 18, 2026

Copy link
Copy Markdown
Member

Add validation for QCOW2 v3 incompatible feature bits, rejecting images that use features not supported by Cloud Hypervisor. Currently only compression (bit 3) is supported.

Till now, images with unsupported features (dirty, corrupt, external data file, extended L2) could be opened without error, potentially causing incorrect behavior or data corruption.

When unsupported features are detected, the feature name table header extension is parsed to provide descriptive error messages. The name table is only read when validation fails, avoiding overhead for valid images.

@weltling
weltling requested a review from a team as a code owner January 18, 2026 21:10
@weltling
weltling force-pushed the qcow-v3-feature-name-table branch 2 times, most recently from 0efb9ee to c174a63 Compare January 18, 2026 22:10

@phip1611 phip1611 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for your contribution - it's good to have a broader safety net for users. I left a comment; otherwise, LGTM.

Comment thread block/src/qcow/mod.rs Outdated
@weltling
weltling force-pushed the qcow-v3-feature-name-table branch 2 times, most recently from fc04678 to cf00efa Compare January 19, 2026 11:10
@weltling
weltling requested a review from phip1611 January 19, 2026 11:27

@phip1611 phip1611 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looking good, I however think we can simplify the code and improve the error reporting even further. My main concern: #7612 (comment)

In case I'm missing something or you can't use bitflags for some reason, feel free to reach out to me again!

Comment thread block/src/qcow/mod.rs Outdated
Comment thread block/src/qcow/mod.rs Outdated
Comment thread block/src/qcow/mod.rs Outdated
@@ -323,6 +366,30 @@ impl QcowHeader {
Ok(())
}

fn report_unsupported_features(unsupported: u64, feature_table: &[(u8, String)]) -> Error {
let features: Vec<String> = (0u8..64)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

with bitflags, this would become let features = FeatureBits::from_bits_retain()

@weltling
weltling force-pushed the qcow-v3-feature-name-table branch from cf00efa to 5222ccd Compare January 19, 2026 16:37
@weltling
weltling requested a review from phip1611 January 19, 2026 16:38
@weltling
weltling force-pushed the qcow-v3-feature-name-table branch from 5222ccd to 7f1cd6e Compare January 22, 2026 12:31

@phip1611 phip1611 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Almost there! Just a few more nits to integrate this nicely with the existing error infrastructure (std::err::Error).

It would be also great if you can run CHV where you artificially let Cloud Hypervisor fail with this error so that we can see the error chain that this produces. Similar to this but with your new error type:

cloud-hypervisor --kernel /etc/bootitems/linux/kernel_minimal/stable.bzImage --cmdline "console=ttyS0" --serial tty --console off --initramfs /etc/bootitems/linux/initrd_minimal/default --firmware a
cloud-hypervisor:   0.001595s: <main> ERROR:/build/source/cloud-hypervisor/src/lib.rs:23 -- Fatal error: ParsingConfig(Validation(PayloadError(FirmwarePlusOtherPayloads)))
Error: Cloud Hypervisor exited with the following chain of errors:
  0: Error parsing config
  1: Error validating configuration
  2: Payload configuration is not bootable
  3: Specifying a kernel is not supported when a firmware is provided

Comment thread block/src/qcow/mod.rs
Comment thread block/src/qcow/mod.rs Outdated
@@ -116,6 +117,8 @@ pub enum Error {
UnsupportedBackingFileFormat(String),
#[error("Unsupported compression type")]
UnsupportedCompressionType,
#[error("Unsupported qcow2 feature(s): {0}")]

@phip1611 phip1611 Jan 22, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
#[error("Unsupported qcow2 feature(s): {0}")]
#[error("Unsupported qcow2 feature(s)")]

this is okay as if we have a proper std::err::Error impl, we will print the underlying error as part of the error chain when Cloud Hypervisor fails

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed, thanks.

Comment thread block/src/qcow/mod.rs Outdated
Comment thread block/src/qcow/mod.rs

/// Error type for unsupported incompatible features.
#[derive(Debug, Clone)]
pub struct MissingFeatureError {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

missing impl of std::err:Error. You should derive thiserror::Error here. Look at other types in the repo that do similar things

@weltling weltling Jan 22, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Using #[derive(Error)] isn't possible here because the Display impl has runtime logic. All existing usages of Error seem to have static error messages, though. Thus, I went for the manual impl which keeps the structured data while participating in the error chain.

Thanks

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Actually, I initially misremembered that #[derive(Error)] requires the #[error("...")] attribute to generate Display. But thiserror seems to detect if a Display impl already exists. So the separate impl std::error::Error was unnecessary. Fixed as suggested, thanks.

Comment thread block/src/qcow/mod.rs Outdated
@weltling
weltling force-pushed the qcow-v3-feature-name-table branch from 7f1cd6e to 766f232 Compare January 22, 2026 19:06
@weltling

Copy link
Copy Markdown
Member Author

@phip1611 thanks for the further hints! That's where you learn about the error hierarchy when you thought you already knew it :)

Following your sugestion, here's some quick bash to run

qemu-img create -f qcow2 /tmp/test-incompat.qcow2 8M 
python3 -c "import struct; f=open('/tmp/test-incompat.qcow2','r+b'); f.seek(72); f.write(struct.pack('>Q', (1<<2)|(1<<4))); f.close()"
cargo build 
./target/debug/cloud-hypervisor --kernel /dev/null --disk path=/tmp/test-incompat.qcow2

With the output shown

cloud-hypervisor:   0.015818s: <main> ERROR:/home/weltling/dws/virt/cloud-hypervisor/cloud-hypervisor/src/lib.rs:23 -- Fatal error: VmBoot(VmBoot(DeviceManager(CreateQcowDiskSync(UnsupportedFeature(MissingFeatureError { features: IncompatFeatures(DATA_FILE | EXTENDED_L2), feature_names: [(0, "dirty bit"), (1, "corrupt bit"), (2, "external data file"), (3, "compression type"), (4, "extended L2 entries")] })))))
Error: Cloud Hypervisor exited with the following chain of errors:
  0: Error booting VM
  1: The VM could not boot
  2: Error from device manager
  3: Failed to create QcowDiskSync
  4: Unsupported qcow2 feature(s)
  5: Missing features: external data file, extended L2 entries

I see the Rust manual suggests an error message to be lower case. I just made "Missing" capitalized to match the project style.

Thanks

@weltling
weltling force-pushed the qcow-v3-feature-name-table branch from 766f232 to 68ce97e Compare January 22, 2026 19:59
@weltling
weltling requested a review from phip1611 January 22, 2026 20:45
@phip1611

Copy link
Copy Markdown
Member

With the output shown

Lovely! Thanks, great work!

I see the Rust manual suggests an error message to be lower case. I just made "Missing" capitalized to match the project style.

Yup, that's a Cloud Hypervisor thingy we have. Thanks!

@phip1611 phip1611 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good job, thanks for your contribution

Parse the feature name table header extension to provide descriptive
error messages when unsupported incompatible features are detected.
Currently only the compression bit (bit 3, zstd) is supported.

This prevents opening qcow2 images with features that would cause
incorrect behavior or data corruption (e.g., dirty bit, corrupt bit,
external data file, extended L2 entries).

Feature names are defined as follows:
1. The image's feature name table header extension (if present)
2. Hardcoded fallback names for known features
3. Generic "unknown feature bit N" for undefined features

Signed-off-by: Anatol Belski <[email protected]>
Co-developed-by: Philipp Schuster <[email protected]>
Add test cases verifying QCOW2 v3 images with unsupported incompatible
feature bits are correctly rejected.

Signed-off-by: Anatol Belski <[email protected]>
@weltling
weltling force-pushed the qcow-v3-feature-name-table branch from 68ce97e to cc68557 Compare January 23, 2026 10:37
@weltling

Copy link
Copy Markdown
Member Author

Thanks @phip1611 for the thorough review and guidance on the error handling! Added you as Co-developed-by to this one for driving the error infrastructure integration.

@likebreath
likebreath added this pull request to the merge queue Jan 23, 2026
Merged via the queue into cloud-hypervisor:main with commit e61901d Jan 23, 2026
48 of 49 checks passed
@weltling
weltling deleted the qcow-v3-feature-name-table branch January 23, 2026 22:30
@github-project-automation github-project-automation Bot moved this from 🆕 New to ✅ Done in Cloud Hypervisor Roadmap Feb 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

3 participants