/* * VAS_EBOOT -- GRand Unified Bootloader * Copyright (C) 2023 Free Software Foundation, Inc. * * VAS_EBOOT 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. * * VAS_EBOOT 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 VAS_EBOOT. If not, see . * * Implementation of the Boot Loader Interface. */ #include #include #include #include #include #include #include #include #include #include #include #include VAS_EBOOT_MOD_LICENSE ("GPLv3+"); #define MODNAME "bli" static const VasEBoot_guid_t bli_vendor_guid = VAS_EBOOT_EFI_VENDOR_BOOT_LOADER_INTERFACE_GUID; static VasEBoot_err_t get_part_uuid (const char *device_name, char **part_uuid) { VasEBoot_device_t device; VasEBoot_err_t status = VAS_EBOOT_ERR_NONE; VasEBoot_disk_t disk = NULL; struct VasEBoot_gpt_partentry entry; device = VasEBoot_device_open (device_name); if (device == NULL) return VasEBoot_error (VasEBoot_errno, N_("cannot open device: %s"), device_name); if (device->disk == NULL) { VasEBoot_dprintf ("bli", "%s is not a disk device, partuuid skipped\n", device_name); *part_uuid = NULL; VasEBoot_device_close (device); return VAS_EBOOT_ERR_NONE; } if (device->disk->partition == NULL) { VasEBoot_dprintf ("bli", "%s has no partition, partuuid skipped\n", device_name); *part_uuid = NULL; VasEBoot_device_close (device); return VAS_EBOOT_ERR_NONE; } disk = VasEBoot_disk_open (device->disk->name); if (disk == NULL) { status = VasEBoot_error (VasEBoot_errno, N_("cannot open disk: %s"), device_name); VasEBoot_device_close (device); return status; } if (VasEBoot_strcmp (device->disk->partition->partmap->name, "gpt") != 0) { status = VasEBoot_error (VAS_EBOOT_ERR_BAD_PART_TABLE, N_("this is not a GPT partition table: %s"), device_name); goto fail; } if (VasEBoot_disk_read (disk, device->disk->partition->offset, device->disk->partition->index, sizeof (entry), &entry) != VAS_EBOOT_ERR_NONE) { status = VasEBoot_error (VasEBoot_errno, N_("read error: %s"), device_name); goto fail; } *part_uuid = VasEBoot_xasprintf ("%pG", &entry.guid); if (*part_uuid == NULL) status = VasEBoot_errno; fail: VasEBoot_disk_close (disk); VasEBoot_device_close (device); return status; } static VasEBoot_err_t set_loader_device_part_uuid (void) { VasEBoot_efi_loaded_image_t *image; char *device_name; VasEBoot_err_t status = VAS_EBOOT_ERR_NONE; char *part_uuid = NULL; image = VasEBoot_efi_get_loaded_image (VasEBoot_efi_image_handle); if (image == NULL) return VasEBoot_error (VAS_EBOOT_ERR_BAD_DEVICE, N_("unable to find boot device")); device_name = VasEBoot_efidisk_get_device_name (image->device_handle); if (device_name == NULL) return VasEBoot_error (VAS_EBOOT_ERR_BAD_DEVICE, N_("unable to find boot device")); status = get_part_uuid (device_name, &part_uuid); if (status == VAS_EBOOT_ERR_NONE && part_uuid) status = VasEBoot_efi_set_variable_to_string ("LoaderDevicePartUUID", &bli_vendor_guid, part_uuid, VAS_EBOOT_EFI_VARIABLE_BOOTSERVICE_ACCESS | VAS_EBOOT_EFI_VARIABLE_RUNTIME_ACCESS); else VasEBoot_error (status, N_("unable to determine partition UUID of boot device")); VasEBoot_free (part_uuid); VasEBoot_free (device_name); return status; } static VasEBoot_err_t set_loader_active_pcr_banks (void) { VasEBoot_efi_uint32_t active_pcr_banks; char *active_pcr_banks_str; VasEBoot_err_t status; active_pcr_banks = VasEBoot_tpm2_active_pcr_banks(); active_pcr_banks_str = VasEBoot_xasprintf ("0x%08x", active_pcr_banks); if (active_pcr_banks_str == NULL) return VasEBoot_error (VAS_EBOOT_ERR_OUT_OF_MEMORY, N_("cannot allocate active PCR banks string")); status = VasEBoot_efi_set_variable_to_string ("LoaderTpm2ActivePcrBanks", &bli_vendor_guid, active_pcr_banks_str, VAS_EBOOT_EFI_VARIABLE_BOOTSERVICE_ACCESS | VAS_EBOOT_EFI_VARIABLE_RUNTIME_ACCESS); VasEBoot_free (active_pcr_banks_str); return status; } VAS_EBOOT_MOD_INIT (bli) { VasEBoot_efi_set_variable_to_string ("LoaderInfo", &bli_vendor_guid, PACKAGE_STRING, VAS_EBOOT_EFI_VARIABLE_BOOTSERVICE_ACCESS | VAS_EBOOT_EFI_VARIABLE_RUNTIME_ACCESS); set_loader_device_part_uuid (); set_loader_active_pcr_banks (); /* No error here is critical, other than being logged */ VasEBoot_print_error (); }