Commit 77c2f2a3 authored by Gen Zhang's avatar Gen Zhang Committed by Thadeu Lima de Souza Cascardo

efi/x86/Add missing error handling to old_memmap 1:1 mapping code

The old_memmap flow in efi_call_phys_prolog() performs numerous memory
allocations, and either does not check for failure at all, or it does
but fails to propagate it back to the caller, which may end up calling
into the firmware with an incomplete 1:1 mapping.

So let's fix this by returning NULL from efi_call_phys_prolog() on
memory allocation failures only, and by handling this condition in the
caller. Also, clean up any half baked sets of page tables that we may
have created before returning with a NULL return value.

Note that any failure at this level will trigger a panic() two levels
up, so none of this makes a huge difference, but it is a nice cleanup
nonetheless.

[ardb: update commit log, add efi_call_phys_epilog() call on error path]
Signed-off-by: default avatarGen Zhang <blackgod016574@gmail.com>
Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rob Bradford <robert.bradford@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/20190525112559.7917-2-ard.biesheuvel@linaro.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>

CVE-2019-12380
(backported from commit 4e78921b)
[ ben_r: backport drops nearly entire patch. The 4.4 kernel skips
  restore of save_pgd if EFI_OLD_MEMMAP isn't set and returns NULL. We
  should not fail out in this case, so we check both conditions instead,
  and return an error code that exists in this tree. ]
Signed-off-by: default avatarBenjamin M Romer <benjamin.romer@canonical.com>
Acked-by: default avatarStefan Bader <stefan.bader@canonical.com>
Acked-by: default avatarThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Signed-off-by: default avatarThadeu Lima de Souza Cascardo <cascardo@canonical.com>
parent 52ae76ef
......@@ -89,6 +89,8 @@ static efi_status_t __init phys_efi_set_virtual_address_map(
pgd_t *save_pgd;
save_pgd = efi_call_phys_prolog();
if (!save_pgd && efi_enabled(EFI_OLD_MEMMAP))
return EFI_BAD_BUFFER_SIZE;
/* Disable interrupts around EFI calls: */
local_irq_save(flags);
......
......@@ -92,6 +92,8 @@ pgd_t * __init efi_call_phys_prolog(void)
n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL);
if (!save_pgd)
return NULL;
for (pgd = 0; pgd < n_pgds; pgd++) {
save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment