@samitouri / QOSamiQemu / commits / f252769a23

hw/uefi: fix buffer overruns

The buffer size checks do not consider the mm_header size, simliar to CVE-2026-5744. Factor out the repeated size check to a small helper function, fix the check, update all places to use the new helper. Fixes: CVE-2026-41435 Fixes: db1ecfb473ac ("hw/uefi: add var-service-vars.c") Reported-by: Katherine Leaver <katherine.j.leaver@gmail.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-ID: <20260422092910.444997-2-kraxel@redhat.com>

Gerd Hoffmann committed Apr 22, 2026 at 11:29 UTC f252769a23e67765f9b95d8944ca3da6c9edf58b
1 file changed +15 -4
hw/uefi/var-service-vars.c
+15 -4
@@ -297,6 +297,17 @@ static size_t uefi_vars_mm_error(mm_header *mhdr, mm_variable *mvar,
297 return sizeof(*mvar);
298 }
299
300 +static bool check_buffer_size(uefi_vars_state *uv, uint64_t length)
301 +{
302 + /* uefi_vars_cmd_mm() checks that */
303 + g_assert(uv->buf_size >= sizeof(mm_header));
304 +
305 + if (uv->buf_size - sizeof(mm_header) < length) {
306 + return false;
307 + }
308 + return true;
309 +}
310 +
311 static size_t uefi_vars_mm_get_variable(uefi_vars_state *uv, mm_header *mhdr,
312 mm_variable *mvar, void *func)
313 {
@@ -344,7 +355,7 @@ static size_t uefi_vars_mm_get_variable(uefi_vars_state *uv, mm_header *mhdr,
355 if (uadd64_overflow(length, va->data_size, &length)) {
356 return uefi_vars_mm_error(mhdr, mvar, EFI_BAD_BUFFER_SIZE);
357 }
347 - if (uv->buf_size < length) {
358 + if (!check_buffer_size(uv, length)) {
359 return uefi_vars_mm_error(mhdr, mvar, EFI_BAD_BUFFER_SIZE);
360 }
361
@@ -414,7 +425,7 @@ uefi_vars_mm_get_next_variable(uefi_vars_state *uv, mm_header *mhdr,
425 }
426
427 length = sizeof(*mvar) + sizeof(*nv) + var->name_size;
417 - if (uv->buf_size < length) {
428 + if (!check_buffer_size(uv, length)) {
429 return uefi_vars_mm_error(mhdr, mvar, EFI_BAD_BUFFER_SIZE);
430 }
431
@@ -605,7 +616,7 @@ static size_t uefi_vars_mm_variable_info(uefi_vars_state *uv, mm_header *mhdr,
616 uint64_t length;
617
618 length = sizeof(*mvar) + sizeof(*vi);
608 - if (uv->buf_size < length) {
619 + if (!check_buffer_size(uv, length)) {
620 return uefi_vars_mm_error(mhdr, mvar, EFI_BAD_BUFFER_SIZE);
621 }
622
@@ -626,7 +637,7 @@ uefi_vars_mm_get_payload_size(uefi_vars_state *uv, mm_header *mhdr,
637 uint64_t length;
638
639 length = sizeof(*mvar) + sizeof(*ps);
629 - if (uv->buf_size < length) {
640 + if (!check_buffer_size(uv, length)) {
641 return uefi_vars_mm_error(mhdr, mvar, EFI_BAD_BUFFER_SIZE);
642 }
643