@samitouri / QOSamiQemu / commits / 3f24c8a74c

igvm: fix handling of optional variable header types

The IGVM spec defines bit 31 of the variable header type as an optional flag: if set, a loader that does not recognize the header type may safely skip it. If clear, the loader must reject the file. Currently, the optional bit is not stripped before comparing header types, so headers with the bit set fail to match any known type and are rejected. Mask bit 31 before comparing header types throughout the IGVM loader, and skip with a warning any unrecognized header that has the optional bit set. Fixes: c1d466d267cf ("backends/igvm: Add IGVM loader and configuration") Signed-off-by: Luigi Leonardi <leonardi@redhat.com> Message-ID: <20260609-igvm_optional-v2-2-b1f1f08dc40e@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

Luigi Leonardi committed Jun 9, 2026 at 14:29 UTC 3f24c8a74ce89686143be2517b4c1e98651bb913
1 file changed +33 -4
backends/igvm.c
+33 -4
@@ -26,6 +26,25 @@
26 #include <igvm/igvm.h>
27 #include <igvm/igvm_defs.h>
28
29 +#ifndef IGVM_VHT_OPTIONAL_BIT
30 +#define IGVM_VHT_OPTIONAL_BIT (1U << 31)
31 +#endif
32 +
33 +/*
34 + * Bit 31 of the variable header type indicates that the header is
35 + * optional and can be safely ignored by a loader that does not
36 + * support it. If the bit is clear, the file cannot be loaded.
37 + * https://docs.rs/igvm_defs/0.4.0/igvm_defs/struct.IgvmVariableHeaderType.html
38 + */
39 +static IgvmVariableHeaderType igvm_vht_type(IgvmVariableHeaderType type)
40 +{
41 + return type & ~IGVM_VHT_OPTIONAL_BIT;
42 +}
43 +
44 +static bool igvm_vht_optional(IgvmVariableHeaderType type)
45 +{
46 + return !!(type & IGVM_VHT_OPTIONAL_BIT);
47 +}
48
49 /*
50 * Some directives are specific to particular confidential computing platforms.
@@ -132,12 +151,14 @@ static struct QIGVMHandler handlers[] = {
151 qigvm_directive_madt },
152 };
153
135 -static int qigvm_handler(QIgvm *ctx, IgvmVariableHeaderType type, Error **errp)
154 +static int qigvm_handler(QIgvm *ctx, IgvmVariableHeaderType raw_type,
155 + Error **errp)
156 {
157 size_t handler;
158 IgvmHandle header_handle;
159 const uint8_t *header_data;
160 int result;
161 + IgvmVariableHeaderType type = igvm_vht_type(raw_type);
162
163 for (handler = 0; handler < G_N_ELEMENTS(handlers); handler++) {
164 if (handlers[handler].type != type) {
@@ -166,6 +187,13 @@ static int qigvm_handler(QIgvm *ctx, IgvmVariableHeaderType type, Error **errp)
187 igvm_free_buffer(ctx->file, header_handle);
188 return result;
189 }
190 +
191 + if (igvm_vht_optional(raw_type)) {
192 + warn_report("IGVM: Skipping unsupported optional header type 0x%"
193 + PRIX32, type);
194 + return 0;
195 + }
196 +
197 error_setg(errp,
198 "IGVM: Unknown header type encountered when processing file: "
199 "(type 0x%X)",
@@ -787,6 +815,7 @@ static int qigvm_supported_platform_compat_mask(QIgvm *ctx, Error **errp)
815 header_index++) {
816 IgvmVariableHeaderType typ = igvm_get_header_type(
817 ctx->file, IGVM_HEADER_SECTION_PLATFORM, header_index);
818 + typ = igvm_vht_type(typ);
819 if (typ == IGVM_VHT_SUPPORTED_PLATFORM) {
820 header_handle = igvm_get_header(
821 ctx->file, IGVM_HEADER_SECTION_PLATFORM, header_index);
@@ -945,10 +974,10 @@ int qigvm_process_file(IgvmCfg *cfg, MachineState *machine_state,
974 for (ctx.current_header_index = 0;
975 ctx.current_header_index < (unsigned)header_count;
976 ctx.current_header_index++) {
948 - IgvmVariableHeaderType type = igvm_get_header_type(
977 + IgvmVariableHeaderType raw_type = igvm_get_header_type(
978 ctx.file, IGVM_HEADER_SECTION_DIRECTIVE, ctx.current_header_index);
950 - if (!onlyVpContext || (type == IGVM_VHT_VP_CONTEXT)) {
951 - if (qigvm_handler(&ctx, type, errp) < 0) {
979 + if (!onlyVpContext || igvm_vht_type(raw_type) == IGVM_VHT_VP_CONTEXT) {
980 + if (qigvm_handler(&ctx, raw_type, errp) < 0) {
981 goto cleanup_parameters;
982 }
983 }