@samitouri / QOSamiQemu / commits / 4d3b9dc4d1

igvm: Report error on missing parameter area in directive handlers

Parameter areas are how an IGVM file tells QEMU to allocate buffers for runtime information the guest needs — VP count, memory map, MADT and so on. Usage directives reference a parameter area by index to tell QEMU where to write each piece of data. If the index doesn't match any declared parameter area, the data has nowhere to go and should be treated as an error. The directive handlers that look up a parameter area all return 0 (success) when `qigvm_find_param_entry()` can't find it. Therefore, the load succeeds but the guest never gets the expected parameters. Note that the IGVM library already validates parameter area indices when the file is loaded, so this path should only be reachable with a malformed file that bypassed library validation. This is defensive programming against that case. Report the error with error_setg() and return -1 instead. Signed-off-by: Luigi Leonardi <leonardi@redhat.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Message-ID: <20260626-microvm_device_tree-v6-1-9cd13cf057e2@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

Luigi Leonardi committed Jun 26, 2026 at 12:04 UTC 4d3b9dc4d1fb42997d6a49155e54e552a3af3c88
3 files changed +21 -13
backends/igvm.c
+16 -10
@@ -81,7 +81,8 @@ struct QEMU_PACKED sev_id_authentication {
81 #define IGVM_SEV_ID_BLOCK_VERSION 1
82
83 QIgvmParameterData*
84 -qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index)
84 +qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index,
85 + Error **errp)
86 {
87 QIgvmParameterData *param_entry;
88 QTAILQ_FOREACH(param_entry, &igvm->parameter_data, next)
@@ -90,7 +91,8 @@ qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index)
91 return param_entry;
92 }
93 }
93 - warn_report("IGVM: No parameter area for index %u", parameter_area_index);
94 + error_setg(errp, "IGVM: parameter area index %u not found",
95 + parameter_area_index);
96 return NULL;
97 }
98
@@ -528,9 +530,10 @@ static int qigvm_directive_parameter_insert(QIgvm *ctx,
530 return 0;
531 }
532
531 - param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
533 + param_entry = qigvm_find_param_entry(ctx,
534 + param->parameter_area_index, errp);
535 if (param_entry == NULL) {
533 - return 0;
536 + return -1;
537 }
538
539 region = qigvm_prepare_memory(ctx, param->gpa, param_entry->size,
@@ -601,9 +604,10 @@ static int qigvm_directive_memory_map(QIgvm *ctx, const uint8_t *header_data,
604 }
605
606 /* Find the parameter area that should hold the memory map */
604 - param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
607 + param_entry = qigvm_find_param_entry(ctx,
608 + param->parameter_area_index, errp);
609 if (param_entry == NULL) {
606 - return 0;
610 + return -1;
611 }
612
613 max_entry_count = param_entry->size / sizeof(IGVM_VHS_MEMORY_MAP_ENTRY);
@@ -660,9 +664,10 @@ static int qigvm_directive_vp_count(QIgvm *ctx, const uint8_t *header_data,
664 uint32_t *vp_count;
665 CPUState *cpu;
666
663 - param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
667 + param_entry = qigvm_find_param_entry(ctx,
668 + param->parameter_area_index, errp);
669 if (param_entry == NULL) {
665 - return 0;
670 + return -1;
671 }
672
673 vp_count = (uint32_t *)(param_entry->data + param->byte_offset);
@@ -683,9 +688,10 @@ static int qigvm_directive_environment_info(QIgvm *ctx,
688 QIgvmParameterData *param_entry;
689 IgvmEnvironmentInfo *environmental_state;
690
686 - param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
691 + param_entry = qigvm_find_param_entry(ctx,
692 + param->parameter_area_index, errp);
693 if (param_entry == NULL) {
688 - return 0;
694 + return -1;
695 }
696
697 environmental_state =
include/system/igvm-internal.h
+2 -1
@@ -72,6 +72,7 @@ struct QIgvm {
72 IgvmHandle qigvm_file_init(char *filename, Error **errp);
73
74 QIgvmParameterData*
75 -qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index);
75 +qigvm_find_param_entry(QIgvm *igvm, uint32_t parameter_area_index,
76 + Error **errp);
77
78 #endif
target/i386/igvm.c
+3 -2
@@ -191,9 +191,10 @@ int qigvm_directive_madt(QIgvm *ctx, const uint8_t *header_data, Error **errp)
191 int result = 0;
192
193 /* Find the parameter area that should hold the MADT data */
194 - param_entry = qigvm_find_param_entry(ctx, param->parameter_area_index);
194 + param_entry = qigvm_find_param_entry(ctx,
195 + param->parameter_area_index, errp);
196 if (param_entry == NULL) {
196 - return 0;
197 + return -1;
198 }
199
200 GArray *madt = acpi_build_madt_standalone(ctx->machine_state);