From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Dimitri John Ledkov Date: Fri, 11 Jun 2021 13:51:20 +0200 Subject: [PATCH] Allow chainloading EFI apps from loop mounts. Signed-off-by: Dimitri John Ledkov Signed-off-by: Robbie Harwood --- grub-core/disk/loopback.c | 9 +-------- grub-core/loader/efi/chainloader.c | 24 ++++++++++++++++++++++++ include/grub/loopback.h | 30 ++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 8 deletions(-) create mode 100644 include/grub/loopback.h diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c index 4635dcfdeec..11a5e0cbd02 100644 --- a/grub-core/disk/loopback.c +++ b/grub-core/disk/loopback.c @@ -21,20 +21,13 @@ #include #include #include +#include #include #include #include GRUB_MOD_LICENSE ("GPLv3+"); -struct grub_loopback -{ - char *devname; - grub_file_t file; - struct grub_loopback *next; - unsigned long id; -}; - static struct grub_loopback *loopback_list; static unsigned long last_id = 0; diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index 0ec682e2988..efbe2bd38aa 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -907,6 +908,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), grub_efi_status_t status; grub_efi_boot_services_t *b; grub_device_t dev = 0; + grub_device_t orig_dev = 0; grub_efi_device_path_t *dp = NULL; char *filename; void *boot_image = 0; @@ -963,6 +965,16 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), dev = grub_device_open (devname); if (devname) grub_free (devname); + + /* if device is loopback, use underlying dev */ + if (dev && dev->disk->dev->id == GRUB_DISK_DEVICE_LOOPBACK_ID) + { + struct grub_loopback *d; + orig_dev = dev; + d = dev->disk->data; + dev = d->file->device; + } + if (dev == NULL) ; else if (dev->disk) @@ -1069,6 +1081,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), } #endif + if (orig_dev) + { + dev = orig_dev; + orig_dev = 0; + } + rc = grub_linuxefi_secure_validate((void *)(unsigned long)address, fsize); grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc); if (rc > 0) @@ -1092,6 +1110,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), fail: + if (orig_dev) + { + dev = orig_dev; + orig_dev = 0; + } + if (dev) grub_device_close (dev); diff --git a/include/grub/loopback.h b/include/grub/loopback.h new file mode 100644 index 00000000000..3b9a9e32e80 --- /dev/null +++ b/include/grub/loopback.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2019 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#ifndef GRUB_LOOPBACK_HEADER +#define GRUB_LOOPBACK_HEADER 1 + +struct grub_loopback +{ + char *devname; + grub_file_t file; + struct grub_loopback *next; + unsigned long id; +}; + +#endif /* ! GRUB_LOOPBACK_HEADER */