Sync from SUSE:SLFO:Main grub2 revision 63018e250eec224553909fb27623e281
This commit is contained in:
parent
a1d205fd6c
commit
5668489852
188
0001-Streamline-BLS-and-improve-PCR-stability.patch
Normal file
188
0001-Streamline-BLS-and-improve-PCR-stability.patch
Normal file
@ -0,0 +1,188 @@
|
||||
From 8201e8e6fbb7ee992c430679705852ede91efcd6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 20 Aug 2024 12:14:35 +0800
|
||||
Subject: [PATCH] Streamline BLS and improve PCR stability
|
||||
|
||||
Introduce an environment variable enable_blscfg to allow looking for and
|
||||
reading BLS (Boot Loader Specification) configurations right at startup,
|
||||
rather than relying on the traditional grub.cfg. The benefit of this
|
||||
approach is that it eliminates the layer of using an external grub.cfg
|
||||
to piggyback the blscfg command. This change reduces the complexity of
|
||||
managing command sequences, which would otherwise complicate the PCR
|
||||
(Platform Configuration Register) policy. Managing a sequence of
|
||||
commands can be difficult to maintain and ensure they remain in order
|
||||
indefinitely.
|
||||
|
||||
Along the way, we can remove the external grub.cfg and have everything
|
||||
embedded in memdisk and early embedded configurations. This approach
|
||||
significantly improves the overall stability and makes it easier to
|
||||
maintain a consistent and predictable PCR outcome.
|
||||
|
||||
The grubenv in the EFI boot directory can be used to override default
|
||||
settings in the grubbls image, allowing for continued customization.
|
||||
|
||||
By introducing grubbls.efi for managing BLS configuration integration,
|
||||
all necessary modules are built-in, and sensible default settings are
|
||||
applied. This allows us to remove the following hardcoded command
|
||||
sequences in blscfg:
|
||||
|
||||
load_video
|
||||
set gfxpalyload=keep
|
||||
insmod gzio
|
||||
|
||||
Since these are now part of the EFI image, this change effectively
|
||||
simplifies the TPM event log, making it easier to handle with tools like
|
||||
pcr-oracle or systemd-pcrlock.
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 4 ++
|
||||
grub-core/normal/main.c | 82 +++++++++++++++++++++++++++++++++++++
|
||||
include/grub/parser.h | 4 ++
|
||||
3 files changed, 90 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index cbe2a289e..e08f35817 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -953,10 +953,14 @@ static void create_entry (struct bls_entry *entry)
|
||||
|
||||
const char *sdval = grub_env_get("save_default");
|
||||
bool savedefault = ((NULL != sdval) && (grub_strcmp(sdval, "true") == 0));
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ src = grub_xasprintf ("%slinux %s%s%s%s\n"
|
||||
+#else
|
||||
src = grub_xasprintf ("%sload_video\n"
|
||||
"set gfxpayload=keep\n"
|
||||
"insmod gzio\n"
|
||||
"linux %s%s%s%s\n"
|
||||
+#endif
|
||||
"%s%s",
|
||||
savedefault ? "savedefault\n" : "",
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index 03631f07a..8e58ced67 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -113,6 +113,65 @@ read_config_file_getline (char **line, int cont __attribute__ ((unused)),
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+
|
||||
+static void
|
||||
+read_envblk_from_cmdpath (void)
|
||||
+{
|
||||
+ const char *cmdpath;
|
||||
+ char *envfile = NULL;
|
||||
+ int found = 0;
|
||||
+
|
||||
+ cmdpath = grub_env_get ("cmdpath");
|
||||
+
|
||||
+ if (cmdpath)
|
||||
+ envfile = grub_xasprintf ("%s/grubenv", cmdpath);
|
||||
+
|
||||
+ if (envfile)
|
||||
+ {
|
||||
+ grub_file_t file;
|
||||
+
|
||||
+ file = grub_file_open (envfile, GRUB_FILE_TYPE_FS_SEARCH
|
||||
+ | GRUB_FILE_TYPE_NO_DECOMPRESS | GRUB_FILE_TYPE_SKIP_SIGNATURE);
|
||||
+ if (file)
|
||||
+ {
|
||||
+ found = 1;
|
||||
+ grub_file_close (file);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (found)
|
||||
+ {
|
||||
+ char *cfg;
|
||||
+
|
||||
+ cfg = grub_xasprintf ("load_env -f %s\n", envfile);
|
||||
+ grub_parser_execute ((char *)cfg);
|
||||
+ grub_free (cfg);
|
||||
+ }
|
||||
+
|
||||
+ grub_free (envfile);
|
||||
+}
|
||||
+
|
||||
+static grub_menu_t
|
||||
+read_blscfg (void)
|
||||
+{
|
||||
+ grub_menu_t newmenu;
|
||||
+ newmenu = grub_env_get_menu ();
|
||||
+ if (! newmenu)
|
||||
+ {
|
||||
+ newmenu = grub_zalloc (sizeof (*newmenu));
|
||||
+ if (! newmenu)
|
||||
+ return 0;
|
||||
+
|
||||
+ grub_env_set_menu (newmenu);
|
||||
+ }
|
||||
+
|
||||
+ grub_parser_execute ((char *)"blscfg\n");
|
||||
+ return newmenu;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
static grub_menu_t
|
||||
read_config_file (const char *config)
|
||||
{
|
||||
@@ -282,6 +341,26 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
|
||||
grub_boot_time ("Executing config file");
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ const char *val;
|
||||
+
|
||||
+ val = grub_env_get ("enable_blscfg");
|
||||
+ if (val && (val[0] == '1' || val[0] == 'y'))
|
||||
+ read_envblk_from_cmdpath ();
|
||||
+
|
||||
+ /* Above would be used to override enable_blscfg, so verify again */
|
||||
+ val = grub_env_get ("enable_blscfg");
|
||||
+ if (val && (val[0] == '1' || val[0] == 'y'))
|
||||
+ {
|
||||
+ menu = read_blscfg ();
|
||||
+ /* Ignore any error. */
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ /* unset to let configfile and source commands continue to work */
|
||||
+ grub_env_unset ("enable_blscfg");
|
||||
+ goto check_batch;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (config)
|
||||
{
|
||||
menu = read_config_file (config);
|
||||
@@ -307,6 +386,9 @@ grub_normal_execute (const char *config, int nested, int batch)
|
||||
|
||||
grub_boot_time ("Executed config file");
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+ check_batch:
|
||||
+#endif
|
||||
if (! batch)
|
||||
{
|
||||
if (menu && menu->size)
|
||||
diff --git a/include/grub/parser.h b/include/grub/parser.h
|
||||
index 64f9f5cc2..9d702571a 100644
|
||||
--- a/include/grub/parser.h
|
||||
+++ b/include/grub/parser.h
|
||||
@@ -86,7 +86,11 @@ struct grub_parser
|
||||
};
|
||||
typedef struct grub_parser *grub_parser_t;
|
||||
|
||||
+#ifdef GRUB_MACHINE_EFI
|
||||
+grub_err_t EXPORT_FUNC (grub_parser_execute) (char *source);
|
||||
+#else
|
||||
grub_err_t grub_parser_execute (char *source);
|
||||
+#endif
|
||||
|
||||
grub_err_t
|
||||
grub_rescue_parse_line (char *line,
|
||||
--
|
||||
2.46.0
|
||||
|
82
0001-bli-Fix-crash-in-get_part_uuid.patch
Normal file
82
0001-bli-Fix-crash-in-get_part_uuid.patch
Normal file
@ -0,0 +1,82 @@
|
||||
From 552a2de0642bb95dd38fcdb7894ea7e07171975e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 15 Jul 2024 11:43:07 +0800
|
||||
Subject: [PATCH] bli: Fix crash in get_part_uuid
|
||||
|
||||
The get_part_uuid() function made an assumption that the target grub
|
||||
device is a partition device and accessed device->disk->partition
|
||||
without checking for NULL. There are four situations where this
|
||||
assumption is problematic:
|
||||
|
||||
1. The device is a net device instead of a disk.
|
||||
2. The device is an abstraction device, like LVM, RAID, or CRYPTO, which
|
||||
is mostly logical "disk" ((lvmid/<UUID>) and so on).
|
||||
3. Firmware RAID may present the ESP to grub as an EFI disk (hd0) device
|
||||
if it is contained within a Linux software RAID.
|
||||
4. When booting from a cdrom, the ESP is a vfat image indexed by the El
|
||||
Torito boot catalog. The boot device is set to (cd0), corresponding
|
||||
to the cdrom image mounted as an iso9660 filesystem.
|
||||
|
||||
As a result, get_part_uuid() could lead to a NULL pointer dereference
|
||||
and trigger a synchronous exception during boot if the ESP falls into
|
||||
one of these categories. This patch fixes the problem by adding the
|
||||
necessary checks to handle cases where the ESP is not a partition
|
||||
device.
|
||||
|
||||
Additionally, to avoid disrupting the boot process, this patch relaxes
|
||||
the severity of the errors in this context to non-critical. Errors will
|
||||
be logged, but they will not prevent the boot process from continuing.
|
||||
|
||||
Fixes: e0fa7dc84 (bli: Add a module for the Boot Loader Interface)
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Reviewed-By: Oliver Steffen <osteffen@redhat.com>
|
||||
---
|
||||
grub-core/commands/bli.c | 20 +++++++++++++++++++-
|
||||
1 file changed, 19 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
|
||||
index e0d8a54f7..298c5f70a 100644
|
||||
--- a/grub-core/commands/bli.c
|
||||
+++ b/grub-core/commands/bli.c
|
||||
@@ -48,6 +48,22 @@ get_part_uuid (const char *device_name, char **part_uuid)
|
||||
if (device == NULL)
|
||||
return grub_error (grub_errno, N_("cannot open device: %s"), device_name);
|
||||
|
||||
+ if (device->disk == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("bli", "%s is not a disk device, partuuid skipped\n", device_name);
|
||||
+ *part_uuid = NULL;
|
||||
+ grub_device_close (device);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ if (device->disk->partition == NULL)
|
||||
+ {
|
||||
+ grub_dprintf ("bli", "%s has no partition, partuuid skipped\n", device_name);
|
||||
+ *part_uuid = NULL;
|
||||
+ grub_device_close (device);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
disk = grub_disk_open (device->disk->name);
|
||||
if (disk == NULL)
|
||||
{
|
||||
@@ -99,7 +115,7 @@ set_loader_device_part_uuid (void)
|
||||
|
||||
status = get_part_uuid (device_name, &part_uuid);
|
||||
|
||||
- if (status == GRUB_ERR_NONE)
|
||||
+ if (status == GRUB_ERR_NONE && part_uuid)
|
||||
status = grub_efi_set_variable_to_string ("LoaderDevicePartUUID", &bli_vendor_guid, part_uuid,
|
||||
GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
@@ -117,4 +133,6 @@ GRUB_MOD_INIT (bli)
|
||||
GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
|
||||
set_loader_device_part_uuid ();
|
||||
+ /* No error here is critical, other than being logged */
|
||||
+ grub_print_error ();
|
||||
}
|
||||
--
|
||||
2.46.0
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 8b9234c7e482edd49a9b3377da8e48fbd54aab28 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 24 Sep 2024 18:59:34 +0800
|
||||
Subject: [PATCH] efinet: Skip virtual VLAN devices during card enumeration
|
||||
|
||||
Similar to the fix in commit "c52ae4057 efinet: skip virtual IPv4 and
|
||||
IPv6 devices during card enumeration", the UEFI PXE driver creates
|
||||
additional VLAN child devices when a VLAN ID is configured on a network
|
||||
interface associated with a physical NIC. These virtual VLAN devices
|
||||
must be skipped during card enumeration to ensure that the subsequent
|
||||
SNP exclusive open operation targets the correct physical card
|
||||
instances, otherwise packet transfer would fail.
|
||||
|
||||
Example device path with VLAN nodes:
|
||||
|
||||
/MAC(123456789ABC,0x1)/Vlan(20)/IPv4(0.0.0.0,0x0,DHCP,0.0.0.0,0.0.0.0,0.0.0.0)
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/net/drivers/efi/efinet.c | 12 +++++++++++-
|
||||
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
|
||||
index 720b5d0e1..3d0bf34fa 100644
|
||||
--- a/grub-core/net/drivers/efi/efinet.c
|
||||
+++ b/grub-core/net/drivers/efi/efinet.c
|
||||
@@ -280,7 +280,8 @@ grub_efinet_findcards (void)
|
||||
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (child) == GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)
|
||||
&& parent
|
||||
&& GRUB_EFI_DEVICE_PATH_TYPE (parent) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||
- && GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)
|
||||
+ && (GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE
|
||||
+ || GRUB_EFI_DEVICE_PATH_SUBTYPE (parent) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE))
|
||||
continue;
|
||||
|
||||
net = grub_efi_open_protocol (*handle, &net_io_guid,
|
||||
@@ -810,6 +811,15 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
|
||||
dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
dup_ldp->length = sizeof (*dup_ldp);
|
||||
+
|
||||
+ dup_ldp = grub_efi_find_last_device_path (dup_dp);
|
||||
+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_VLAN_DEVICE_PATH_SUBTYPE)
|
||||
+ {
|
||||
+ dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
+ dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
+ dup_ldp->length = sizeof (*dup_ldp);
|
||||
+ }
|
||||
+
|
||||
match = grub_efi_compare_device_paths (dup_dp, cdp) == 0;
|
||||
grub_free (dup_dp);
|
||||
if (!match)
|
||||
--
|
||||
2.46.1
|
||||
|
48
0001-fix-grub-screen-filled-with-post-screen-artifects.patch
Normal file
48
0001-fix-grub-screen-filled-with-post-screen-artifects.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 44f3c7978a8ac5cc94a5c885ac9e983ba2980f5e Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 29 May 2024 12:32:32 +0800
|
||||
Subject: [PATCH] fix grub screen filled with post screen artifects
|
||||
|
||||
---
|
||||
grub-core/normal/menu.c | 7 ++++---
|
||||
grub-core/term/efi/console.c | 2 +-
|
||||
2 files changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index 1df2638d7..b11b28e0d 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -975,13 +975,14 @@ show_menu (grub_menu_t menu, int nested, int autobooted)
|
||||
if (! e)
|
||||
continue; /* Menu is empty. */
|
||||
|
||||
- grub_cls ();
|
||||
-
|
||||
if (auto_boot)
|
||||
grub_menu_execute_with_fallback (menu, e, autobooted,
|
||||
&execution_callback, ¬ify_boot);
|
||||
else
|
||||
- grub_menu_execute_entry (e, 0);
|
||||
+ {
|
||||
+ grub_cls ();
|
||||
+ grub_menu_execute_entry (e, 0);
|
||||
+ }
|
||||
if (autobooted)
|
||||
break;
|
||||
}
|
||||
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
|
||||
index bb587f39d..258b52737 100644
|
||||
--- a/grub-core/term/efi/console.c
|
||||
+++ b/grub-core/term/efi/console.c
|
||||
@@ -432,7 +432,7 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
|
||||
grub_efi_simple_text_output_interface_t *o;
|
||||
grub_efi_int32_t orig_attr;
|
||||
|
||||
- if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE)
|
||||
+ if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE)
|
||||
return;
|
||||
|
||||
o = grub_efi_system_table->con_out;
|
||||
--
|
||||
2.45.1
|
||||
|
@ -1,44 +0,0 @@
|
||||
From a59b58f6ae327a8f6949991cb5531db01e1ba14d Mon Sep 17 00:00:00 2001
|
||||
From: Wen Xiong <wenxiong@linux.ibm.com>
|
||||
Date: Tue, 7 Feb 2023 15:10:15 -0500
|
||||
Subject: [PATCH] grub2: Can't setup a default boot device correctly on nvme
|
||||
device in Beta3
|
||||
|
||||
The patch in Bug 200486 - SUSE1205666 - SLES15SP5 Beta1: Setup multiple dev path
|
||||
for a nvmf boot device in grub2 caused the issue. That patch didn't consider
|
||||
nvme devices carefully.
|
||||
|
||||
The new patch will check "nvme-of" instead of "nvme" to call
|
||||
build_multi_boot_device().
|
||||
|
||||
Signed-off-by: Wen Xiong<wenxiong@linux.ibm.com>
|
||||
---
|
||||
grub-core/osdep/unix/platform.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
|
||||
index db8fa4b95..fb47c0ffa 100644
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -288,11 +288,15 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
- else if (grub_strstr(install_device, "nvme"))
|
||||
- boot_device = build_multi_boot_device(install_device);
|
||||
- else
|
||||
+ else {
|
||||
boot_device = get_ofpathname (install_device);
|
||||
|
||||
+ if (grub_strstr(boot_device, "nvme-of")) {
|
||||
+ free (boot_device);
|
||||
+ boot_device = build_multi_boot_device(install_device);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
|
||||
boot_device, NULL }))
|
||||
{
|
||||
--
|
||||
2.39.1
|
||||
|
@ -1,164 +0,0 @@
|
||||
From 3e77c5494fd06f430588ae9c304fea370439d531 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Xiong <Wen Xiong>
|
||||
Date: Thu, 15 Dec 2022 21:33:41 -0500
|
||||
Subject: [PATCH] grub2: Set multiple device path for a nvmf boot device
|
||||
|
||||
nvmf support native multipath(ANA) by default.
|
||||
The patch added the support for setting multiple
|
||||
device path for a nvmf boot device.
|
||||
|
||||
localhost:~ grub2-install -v /dev/nvme1n1p1
|
||||
...
|
||||
...
|
||||
...
|
||||
grub2-install: info: executing nvsetenv boot-device /pci@800000020000132/fibre-channel@0,1/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0,1/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec.
|
||||
Installation finished. No error reported.
|
||||
|
||||
localhost:~ # bootlist -m normal -o
|
||||
nvme7n1
|
||||
nvme5n1
|
||||
nvme1n1
|
||||
nvme4n1
|
||||
|
||||
localhost:~ # bootlist -m normal -r
|
||||
/pci@800000020000132/fibre-channel@0,1/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0,1/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
|
||||
Signed-off-by: Wen Xiong <wenxiong@linux.ibm.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 6 ++---
|
||||
grub-core/osdep/unix/platform.c | 48 +++++++++++++++++++++++++++++++++
|
||||
include/grub/util/install.h | 3 +++
|
||||
include/grub/util/ofpath.h | 9 +++++++
|
||||
4 files changed, 63 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -209,7 +209,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
xrealpath (const char *in)
|
||||
{
|
||||
char *out;
|
||||
@@ -224,7 +224,7 @@
|
||||
return out;
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
block_device_get_sysfs_path_and_link(const char *devicenode)
|
||||
{
|
||||
char *rpath;
|
||||
@@ -535,7 +535,7 @@
|
||||
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
nvme_get_syspath(const char *nvmedev)
|
||||
{
|
||||
char *sysfs_path, *controller_node;
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <grub/util/install.h>
|
||||
+#include <grub/util/ofpath.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/util/misc.h>
|
||||
#include <grub/misc.h>
|
||||
@@ -131,6 +132,51 @@
|
||||
return rc;
|
||||
}
|
||||
|
||||
+char *
|
||||
+build_multi_boot_device(const char *install_device)
|
||||
+{
|
||||
+ char *sysfs_path;
|
||||
+ char *nvme_ns;
|
||||
+ unsigned int nsid;
|
||||
+ char *ptr;
|
||||
+ char *boot_device_string;
|
||||
+ struct dirent *ep;
|
||||
+ DIR *dp;
|
||||
+
|
||||
+ nvme_ns = strchr(install_device, 'n');
|
||||
+ nsid = of_path_get_nvme_nsid(nvme_ns);
|
||||
+ sysfs_path = nvme_get_syspath(nvme_ns);
|
||||
+ strcat(sysfs_path, "/device");
|
||||
+ sysfs_path = xrealpath(sysfs_path);
|
||||
+
|
||||
+ dp = opendir(sysfs_path);
|
||||
+ ptr = boot_device_string = xmalloc (1000);
|
||||
+
|
||||
+ /* We cannot have a boot list with more than five entries */
|
||||
+ while((ep = readdir(dp)) != NULL){
|
||||
+ char *nvme_device;
|
||||
+
|
||||
+ if (grub_strstr(ep->d_name, "nvme")) {
|
||||
+ nvme_device = xasprintf ("%s%s%x ",
|
||||
+ get_ofpathname(ep->d_name),"/namespace@", nsid);
|
||||
+ if ((strlen(boot_device_string) + strlen(nvme_device)) >= 200*5 - 1) {
|
||||
+ grub_util_warn (_("More than five entries cannot be specified in the bootlist"));
|
||||
+ free(nvme_device);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ strncpy(ptr, nvme_device, strlen(nvme_device));
|
||||
+ ptr += strlen(nvme_device);
|
||||
+ free(nvme_device);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *--ptr = '\0';
|
||||
+ closedir(dp);
|
||||
+
|
||||
+ return boot_device_string;
|
||||
+}
|
||||
+
|
||||
int
|
||||
grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
const char *efifile_path,
|
||||
@@ -242,6 +288,8 @@
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
+ else if (grub_strstr(install_device, "nvme"))
|
||||
+ boot_device = build_multi_boot_device(install_device);
|
||||
else
|
||||
boot_device = get_ofpathname (install_device);
|
||||
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -241,6 +241,9 @@
|
||||
const char *efi_distributor,
|
||||
const char *force_disk);
|
||||
|
||||
+char *
|
||||
+build_multi_boot_device(const char *install_device);
|
||||
+
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath);
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -32,4 +32,13 @@
|
||||
|
||||
char* of_find_fc_host(char* host_wwpn);
|
||||
|
||||
+char* nvme_get_syspath(const char *nvmedev);
|
||||
+
|
||||
+char* block_device_get_sysfs_path_and_link(const char *devicenode);
|
||||
+
|
||||
+char* xrealpath (const char *in);
|
||||
+
|
||||
+unsigned int of_path_get_nvme_nsid(const char* devname);
|
||||
+
|
||||
+
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
171
0001-ieee1275-Platform-Keystore-PKS-Support.patch
Normal file
171
0001-ieee1275-Platform-Keystore-PKS-Support.patch
Normal file
@ -0,0 +1,171 @@
|
||||
From 04e8509f04a4cd123bc9f290e60f582d57b2f258 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Tue, 27 Dec 2022 17:47:41 +0530
|
||||
Subject: [PATCH 1/8] ieee1275: Platform Keystore (PKS) Support
|
||||
|
||||
enhancing the infrastructure to enable the Platform Keystore (PKS) feature,
|
||||
which provides access to the SB VERSION, DB, and DBX secure boot variables
|
||||
from PKS.
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Tested-by: Nageswara Sastry <rnsastry@linux.ibm.com>
|
||||
---
|
||||
grub-core/kern/ieee1275/ieee1275.c | 117 +++++++++++++++++++++++++++++
|
||||
include/grub/ieee1275/ieee1275.h | 15 ++++
|
||||
2 files changed, 132 insertions(+)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/ieee1275.c b/grub-core/kern/ieee1275/ieee1275.c
|
||||
index 36ca2dbfc..8d0048844 100644
|
||||
--- a/grub-core/kern/ieee1275/ieee1275.c
|
||||
+++ b/grub-core/kern/ieee1275/ieee1275.c
|
||||
@@ -807,3 +807,120 @@ grub_ieee1275_get_block_size (grub_ieee1275_ihandle_t ihandle)
|
||||
|
||||
return args.size;
|
||||
}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_test (const char *name, grub_ieee1275_cell_t *missing)
|
||||
+{
|
||||
+ struct test_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t name;
|
||||
+ grub_ieee1275_cell_t missing;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "test", 1, 1);
|
||||
+ args.name = (grub_ieee1275_cell_t) name;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.missing == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *missing = args.missing;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_max_object_size (grub_size_t *result)
|
||||
+{
|
||||
+ struct mos_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t size;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-max-object-size", 0, 1);
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.size == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *result = args.size;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_read_object (grub_uint8_t consumer, grub_uint8_t *label,
|
||||
+ grub_size_t label_len, grub_uint8_t *buffer,
|
||||
+ grub_size_t buffer_len, grub_size_t *data_len,
|
||||
+ grub_uint32_t *policies)
|
||||
+{
|
||||
+ struct pks_read_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t consumer;
|
||||
+ grub_ieee1275_cell_t label;
|
||||
+ grub_ieee1275_cell_t label_len;
|
||||
+ grub_ieee1275_cell_t buffer;
|
||||
+ grub_ieee1275_cell_t buffer_len;
|
||||
+ grub_ieee1275_cell_t data_len;
|
||||
+ grub_ieee1275_cell_t policies;
|
||||
+ grub_ieee1275_cell_t rc;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-read-object", 5, 3);
|
||||
+ args.consumer = (grub_ieee1275_cell_t) consumer;
|
||||
+ args.label = (grub_ieee1275_cell_t) label;
|
||||
+ args.label_len = (grub_ieee1275_cell_t) label_len;
|
||||
+ args.buffer = (grub_ieee1275_cell_t) buffer;
|
||||
+ args.buffer_len = (grub_ieee1275_cell_t) buffer_len;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.data_len == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *data_len = args.data_len;
|
||||
+ *policies = args.policies;
|
||||
+
|
||||
+ return (int) args.rc;
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+grub_ieee1275_pks_read_sbvar (grub_uint8_t sbvarflags, grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t *buffer, grub_size_t buffer_len,
|
||||
+ grub_size_t *data_len)
|
||||
+{
|
||||
+ struct pks_read_sbvar_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t sbvarflags;
|
||||
+ grub_ieee1275_cell_t sbvartype;
|
||||
+ grub_ieee1275_cell_t buffer;
|
||||
+ grub_ieee1275_cell_t buffer_len;
|
||||
+ grub_ieee1275_cell_t data_len;
|
||||
+ grub_ieee1275_cell_t rc;
|
||||
+ } args;
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&args.common, "pks-read-sbvar", 4, 2);
|
||||
+ args.sbvarflags = (grub_ieee1275_cell_t) sbvarflags;
|
||||
+ args.sbvartype = (grub_ieee1275_cell_t) sbvartype;
|
||||
+ args.buffer = (grub_ieee1275_cell_t) buffer;
|
||||
+ args.buffer_len = (grub_ieee1275_cell_t) buffer_len;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (args.data_len == IEEE1275_CELL_INVALID)
|
||||
+ return -1;
|
||||
+
|
||||
+ *data_len = args.data_len;
|
||||
+
|
||||
+ return (int) args.rc;
|
||||
+}
|
||||
diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h
|
||||
index ea90d79f7..6d8dd9463 100644
|
||||
--- a/include/grub/ieee1275/ieee1275.h
|
||||
+++ b/include/grub/ieee1275/ieee1275.h
|
||||
@@ -237,6 +237,21 @@ char *EXPORT_FUNC(grub_ieee1275_encode_uint4) (grub_ieee1275_ihandle_t ihandle,
|
||||
grub_size_t *size);
|
||||
int EXPORT_FUNC(grub_ieee1275_get_block_size) (grub_ieee1275_ihandle_t ihandle);
|
||||
|
||||
+int EXPORT_FUNC (grub_ieee1275_test) (const char *name,
|
||||
+ grub_ieee1275_cell_t *missing);
|
||||
+
|
||||
+// not exported: I don't want modules interacting with PKS.
|
||||
+int grub_ieee1275_pks_max_object_size (grub_size_t *result);
|
||||
+
|
||||
+int grub_ieee1275_pks_read_object (grub_uint8_t consumer, grub_uint8_t *label,
|
||||
+ grub_size_t label_len, grub_uint8_t *buffer,
|
||||
+ grub_size_t buffer_len, grub_size_t *data_len,
|
||||
+ grub_uint32_t *policies);
|
||||
+
|
||||
+int grub_ieee1275_pks_read_sbvar (grub_uint8_t sbvarflags, grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t *buffer, grub_size_t buffer_len,
|
||||
+ grub_size_t *data_len);
|
||||
+
|
||||
grub_err_t EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size);
|
||||
void EXPORT_FUNC(grub_releasemap) (void);
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
170
0001-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
Normal file
170
0001-ieee1275-support-added-for-multiple-nvme-bootpaths.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From 219b06c69d38a10349183002efb82bfec3b7ff5b Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Wed, 21 Aug 2024 14:13:05 +0530
|
||||
Subject: [PATCH] ieee1275: support added for multiple nvme bootpaths
|
||||
|
||||
This patch sets mupltiple NVMe boot-devices for more robust boot.
|
||||
Scenario where NVMe multipaths are available, all the available bootpaths (Max 5)
|
||||
will be added as the boot-device.
|
||||
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 6 +--
|
||||
grub-core/osdep/unix/platform.c | 65 ++++++++++++++++++++++++++++++++-
|
||||
include/grub/util/install.h | 3 ++
|
||||
include/grub/util/ofpath.h | 4 ++
|
||||
4 files changed, 74 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 51d331f06..55ed7ddf2 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -209,7 +209,7 @@ find_obppath (const char *sysfs_path_orig)
|
||||
}
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
xrealpath (const char *in)
|
||||
{
|
||||
char *out;
|
||||
@@ -224,7 +224,7 @@ xrealpath (const char *in)
|
||||
return out;
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
block_device_get_sysfs_path_and_link(const char *devicenode)
|
||||
{
|
||||
char *rpath;
|
||||
@@ -535,7 +535,7 @@ of_path_get_nvme_nsid(const char* devname)
|
||||
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
nvme_get_syspath(const char *nvmedev)
|
||||
{
|
||||
char *sysfs_path, *controller_node;
|
||||
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
|
||||
index 1e2961e00..bafcc84d7 100644
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
+#include <grub/util/ofpath.h>
|
||||
+#define BOOTDEV_BUFFER 1000
|
||||
|
||||
static char *
|
||||
get_ofpathname (const char *dev)
|
||||
@@ -203,6 +205,56 @@ grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+char *
|
||||
+add_multiple_nvme_bootdevices (const char *install_device)
|
||||
+{
|
||||
+ char *sysfs_path, *nvme_ns, *ptr;
|
||||
+ unsigned int nsid;
|
||||
+ char *multipath_boot;
|
||||
+ struct dirent *ep;
|
||||
+ DIR *dp;
|
||||
+
|
||||
+ /*
|
||||
+ * Extracting the namespace from install_device.
|
||||
+ * ex. install_device : /dev/nvme1n1
|
||||
+ */
|
||||
+ nvme_ns = grub_strstr (install_device, "nvme");
|
||||
+ nsid = of_path_get_nvme_nsid (nvme_ns);
|
||||
+ if (nsid == 0)
|
||||
+ return NULL;
|
||||
+
|
||||
+ sysfs_path = nvme_get_syspath (nvme_ns);
|
||||
+ strcat (sysfs_path, "/subsystem");
|
||||
+ sysfs_path = xrealpath (sysfs_path);
|
||||
+ dp = opendir (sysfs_path);
|
||||
+ if (!dp)
|
||||
+ return NULL;
|
||||
+
|
||||
+ ptr = multipath_boot = xmalloc (BOOTDEV_BUFFER);
|
||||
+ while ((ep = readdir (dp)) != NULL)
|
||||
+ {
|
||||
+ char *path;
|
||||
+ if (grub_strstr (ep->d_name, "nvme"))
|
||||
+ {
|
||||
+ path = xasprintf ("%s%s%x ", get_ofpathname (ep->d_name), "/namespace@", nsid);
|
||||
+ if ((strlen (multipath_boot) + strlen (path)) > BOOTDEV_BUFFER)
|
||||
+ {
|
||||
+ grub_util_warn (_("Maximum five entries are allowed in the bootlist"));
|
||||
+ free (path);
|
||||
+ break;
|
||||
+ }
|
||||
+ strncpy (ptr, path, strlen (path));
|
||||
+ ptr += strlen (path);
|
||||
+ free (path);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *--ptr = '\0';
|
||||
+ closedir (dp);
|
||||
+
|
||||
+ return multipath_boot;
|
||||
+}
|
||||
+
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath)
|
||||
@@ -242,8 +294,19 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
+ else if (grub_strstr (install_device, "nvme"))
|
||||
+ {
|
||||
+ boot_device = add_multiple_nvme_bootdevices (install_device);
|
||||
+ }
|
||||
else
|
||||
- boot_device = get_ofpathname (install_device);
|
||||
+ {
|
||||
+ boot_device = get_ofpathname (install_device);
|
||||
+ if (grub_strstr (boot_device, "nvme-of"))
|
||||
+ {
|
||||
+ free (boot_device);
|
||||
+ boot_device = add_multiple_nvme_bootdevices (install_device);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
|
||||
boot_device, NULL }))
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index 563cf68e9..2fd102649 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -241,6 +241,9 @@ grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
const char *efi_distributor,
|
||||
const char *force_disk);
|
||||
|
||||
+char *
|
||||
+add_multiple_nvme_bootdevices (const char *install_device);
|
||||
+
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath);
|
||||
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
|
||||
index a0ec30620..cc3c4bfbd 100644
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -31,5 +31,9 @@ void add_filename_to_pile(char *filename, struct ofpath_files_list_root* root);
|
||||
void find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth);
|
||||
|
||||
char* of_find_fc_host(char* host_wwpn);
|
||||
+char* nvme_get_syspath (const char *nvmedev);
|
||||
+char* block_device_get_sysfs_path_and_link (const char *devicenode);
|
||||
+char* xrealpath (const char *in);
|
||||
+unsigned int of_path_get_nvme_nsid (const char* devname);
|
||||
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
||||
--
|
||||
2.47.0
|
||||
|
122
0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch
Normal file
122
0001-kern-ieee1275-init-Add-IEEE-1275-Radix-support-for-K.patch
Normal file
@ -0,0 +1,122 @@
|
||||
From ba65f46ffd2952a3f69d85a4534b1e55291f080c Mon Sep 17 00:00:00 2001
|
||||
From: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Date: Thu, 23 May 2024 18:43:14 +0530
|
||||
Subject: [PATCH] kern/ieee1275/init: Add IEEE 1275 Radix support for KVM on
|
||||
Power
|
||||
|
||||
This patch adds support for Radix, Xive and Radix_gtse in Options
|
||||
vector5 which is required for KVM LPARs. KVM LPARs ONLY support
|
||||
Radix and not the Hash. Not enabling Radix on any PowerVM KVM LPARs
|
||||
will result in boot failure.
|
||||
|
||||
Signed-off-by: Avnish Chouhan <avnish@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/ieee1275/init.c | 63 +++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 62 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index bb800b275..8e08e5dd5 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -115,6 +115,16 @@ grub_addr_t grub_ieee1275_original_stack;
|
||||
#define DRC_INFO 0x40
|
||||
#define BYTE22 (DY_MEM_V2 | DRC_INFO)
|
||||
|
||||
+/* For ibm,arch-vec-5-platform-support. */
|
||||
+#define XIVE_INDEX 0x17
|
||||
+#define MMU_INDEX 0x18
|
||||
+#define RADIX_GTSE_INDEX 0x1a
|
||||
+#define RADIX_ENABLED 0x40
|
||||
+#define XIVE_ENABLED 0x40
|
||||
+#define HASH_ENABLED 0x00
|
||||
+#define MAX_SUPPORTED 0xC0
|
||||
+#define RADIX_GTSE_ENABLED 0x40
|
||||
+
|
||||
void
|
||||
grub_exit (void)
|
||||
{
|
||||
@@ -740,6 +750,10 @@ struct option_vector5
|
||||
grub_uint32_t platform_facilities;
|
||||
grub_uint8_t sub_processors;
|
||||
grub_uint8_t byte22;
|
||||
+ grub_uint8_t xive;
|
||||
+ grub_uint8_t mmu;
|
||||
+ grub_uint8_t hpt_ext;
|
||||
+ grub_uint8_t radix_gtse;
|
||||
} GRUB_PACKED;
|
||||
|
||||
struct pvr_entry
|
||||
@@ -778,6 +792,13 @@ grub_ieee1275_ibm_cas (void)
|
||||
{
|
||||
int rc;
|
||||
grub_ieee1275_ihandle_t root;
|
||||
+ grub_uint8_t ibm_arch_platform_support[8];
|
||||
+ grub_ssize_t actual;
|
||||
+ grub_uint8_t xive_support = 0;
|
||||
+ grub_uint8_t mmu_support = 0;
|
||||
+ grub_uint8_t radix_gtse_support = 0;
|
||||
+ int i = 0;
|
||||
+ int prop_len = 8;
|
||||
struct cas_args
|
||||
{
|
||||
struct grub_ieee1275_common_hdr common;
|
||||
@@ -786,6 +807,46 @@ grub_ieee1275_ibm_cas (void)
|
||||
grub_ieee1275_cell_t cas_addr;
|
||||
grub_ieee1275_cell_t result;
|
||||
} args;
|
||||
+
|
||||
+ grub_ieee1275_get_integer_property (grub_ieee1275_chosen,
|
||||
+ "ibm,arch-vec-5-platform-support",
|
||||
+ (grub_uint32_t *) ibm_arch_platform_support,
|
||||
+ sizeof (ibm_arch_platform_support),
|
||||
+ &actual);
|
||||
+
|
||||
+ for (i = 0; i < prop_len; i++)
|
||||
+ {
|
||||
+ switch (ibm_arch_platform_support[i])
|
||||
+ {
|
||||
+ case XIVE_INDEX:
|
||||
+ if (ibm_arch_platform_support[i + 1] & MAX_SUPPORTED)
|
||||
+ xive_support = XIVE_ENABLED;
|
||||
+ else
|
||||
+ xive_support = 0;
|
||||
+ break;
|
||||
+
|
||||
+ case MMU_INDEX:
|
||||
+ if (ibm_arch_platform_support[i + 1] & MAX_SUPPORTED)
|
||||
+ mmu_support = RADIX_ENABLED;
|
||||
+ else
|
||||
+ mmu_support = HASH_ENABLED;
|
||||
+ break;
|
||||
+
|
||||
+ case RADIX_GTSE_INDEX:
|
||||
+ if (mmu_support == RADIX_ENABLED)
|
||||
+ radix_gtse_support = ibm_arch_platform_support[i + 1] & RADIX_GTSE_ENABLED;
|
||||
+ else
|
||||
+ radix_gtse_support = 0;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ /* Ignoring the other indexes of ibm,arch-vec-5-platform-support. */
|
||||
+ break;
|
||||
+ }
|
||||
+ /* Skipping the property value. */
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
struct cas_vector vector =
|
||||
{
|
||||
.pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
|
||||
@@ -802,7 +863,7 @@ grub_ieee1275_ibm_cas (void)
|
||||
.vec4 = 0x0001, /* set required minimum capacity % to the lowest value */
|
||||
.vec5_size = 1 + sizeof (struct option_vector5) - 2,
|
||||
.vec5 = {
|
||||
- 0, BYTE2, 0, CMO, ASSOCIATIVITY, BIN_OPTS, 0, 0, MAX_CPU, 0, 0, PLATFORM_FACILITIES, SUB_PROCESSORS, BYTE22
|
||||
+ 0, BYTE2, 0, CMO, ASSOCIATIVITY, BIN_OPTS, 0, 0, MAX_CPU, 0, 0, PLATFORM_FACILITIES, SUB_PROCESSORS, BYTE22, xive_support, mmu_support, 0, radix_gtse_support
|
||||
}
|
||||
};
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
44
0001-tpm-Skip-loopback-image-measurement.patch
Normal file
44
0001-tpm-Skip-loopback-image-measurement.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From cda4b7a415eb45743ea54a7760b302c0cfe718cf Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 23 Sep 2024 10:32:18 +0800
|
||||
Subject: [PATCH] tpm: Skip loopback image measurement
|
||||
|
||||
The loopback image is configured to function as a disk by being mapped
|
||||
as a block device. Instead of measuring the entire block device, we
|
||||
should focus on tracking the individual files accessed from it. For
|
||||
example, we do not directly measure block devices like disk hd0, but the
|
||||
files opened from it.
|
||||
|
||||
This method is important to avoid running out of memory, since loopback
|
||||
images can be very large. Trying to read and measure the whole image at
|
||||
once could cause out of memory errors and disrupt the boot process.
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/tpm.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c
|
||||
index bb9aee210..ebbb4fef0 100644
|
||||
--- a/grub-core/commands/tpm.c
|
||||
+++ b/grub-core/commands/tpm.c
|
||||
@@ -41,6 +41,16 @@ grub_tpm_verify_init (grub_file_t io,
|
||||
{
|
||||
*context = io->name;
|
||||
*flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK;
|
||||
+
|
||||
+ /*
|
||||
+ * The loopback image is mapped as a disk, allowing it to function like a
|
||||
+ * block device. However, we measure the files read from the block device,
|
||||
+ * not the device itself. For example, we don't measure block devices like
|
||||
+ * disk hd0 directly. This process is crucial to prevent out-of-memory
|
||||
+ * errors, as loopback images are inherently large.
|
||||
+ */
|
||||
+ if ((type & GRUB_FILE_TYPE_MASK) == GRUB_FILE_TYPE_LOOPBACK)
|
||||
+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
--
|
||||
2.46.1
|
||||
|
671
0002-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
Normal file
671
0002-ieee1275-Read-the-DB-and-DBX-secure-boot-variables.patch
Normal file
@ -0,0 +1,671 @@
|
||||
From 8ef821ea18ed35f5969b98f2df6a76fefb71b175 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Date: Wed, 28 Dec 2022 17:49:24 +0530
|
||||
Subject: [PATCH 2/8] ieee1275: Read the DB and DBX secure boot variables
|
||||
|
||||
If secure boot is enabled with PKS, it will read secure boot variables
|
||||
such as db and dbx from PKS and extract certificates from ESL.
|
||||
It would be saved in the platform keystore buffer, and
|
||||
the appendedsig (module) would read it later to extract
|
||||
the certificate's details.
|
||||
|
||||
In the following scenarios, static key mode will be activated:
|
||||
1. When secure boot is enabled with static
|
||||
2. When SB Version is unavailable but Secure Boot is enabled
|
||||
3. When PKS support is unavailable but secure boot is enabled
|
||||
|
||||
Note:-
|
||||
|
||||
SB Version - secure boot mode
|
||||
1 - PKS
|
||||
0 - static key (embeded key)
|
||||
|
||||
Signed-off-by: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Tested-by: Nageswara Sastry <rnsastry@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/kern/ieee1275/init.c | 12 +-
|
||||
grub-core/kern/ieee1275/platform_keystore.c | 377 ++++++++++++++++++++
|
||||
include/grub/platform_keystore.h | 190 ++++++++++
|
||||
5 files changed, 580 insertions(+), 1 deletion(-)
|
||||
create mode 100644 grub-core/kern/ieee1275/platform_keystore.c
|
||||
create mode 100644 include/grub/platform_keystore.h
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index 9d3d5f519..4630e2ba3 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -79,6 +79,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/platform_keystore.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lockdown.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index dc639dd24..4ff35afb7 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -170,6 +170,7 @@ kernel = {
|
||||
ieee1275 = kern/ieee1275/openfw.c;
|
||||
ieee1275 = term/ieee1275/console.c;
|
||||
ieee1275 = kern/ieee1275/init.c;
|
||||
+ ieee1275 = kern/ieee1275/platform_keystore.c;
|
||||
|
||||
uboot = disk/uboot/ubootdisk.c;
|
||||
uboot = kern/uboot/uboot.c;
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index 38f1f1f6e..bb800b275 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <grub/ieee1275/alloc.h>
|
||||
#endif
|
||||
#include <grub/lockdown.h>
|
||||
+#include <grub/platform_keystore.h>
|
||||
|
||||
/* The maximum heap size we're going to claim at boot. Not used by sparc. */
|
||||
#ifdef __i386__
|
||||
@@ -915,7 +916,16 @@ grub_get_ieee1275_secure_boot (void)
|
||||
* We only support enforce.
|
||||
*/
|
||||
if (rc >= 0 && is_sb >= 2)
|
||||
- grub_lockdown ();
|
||||
+ {
|
||||
+ grub_printf ("secure boot enabled\n");
|
||||
+ rc = grub_platform_keystore_init ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_printf ("Warning: initialization of the platform keystore failed!\n");
|
||||
+
|
||||
+ grub_lockdown ();
|
||||
+ }
|
||||
+ else
|
||||
+ grub_printf ("secure boot disabled\n");
|
||||
}
|
||||
|
||||
grub_addr_t grub_modbase;
|
||||
diff --git a/grub-core/kern/ieee1275/platform_keystore.c b/grub-core/kern/ieee1275/platform_keystore.c
|
||||
new file mode 100644
|
||||
index 000000000..976e4e9b5
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/ieee1275/platform_keystore.c
|
||||
@@ -0,0 +1,377 @@
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/lockdown.h>
|
||||
+#include <grub/platform_keystore.h>
|
||||
+
|
||||
+#define PKS_CONSUMER_FW 1
|
||||
+#define SB_VERSION_KEY_NAME ((grub_uint8_t *) "SB_VERSION")
|
||||
+#define SB_VERSION_KEY_LEN 10
|
||||
+#define DB 1
|
||||
+#define DBX 2
|
||||
+
|
||||
+#define PKS_OBJECT_NOT_FOUND -7
|
||||
+#define PKS_UNPACK_ERROR 0x200
|
||||
+#define PKS_UNPACK_VERSION_ERROR 0x201
|
||||
+
|
||||
+struct pks_timestamp
|
||||
+{
|
||||
+ grub_uint16_t year;
|
||||
+ grub_uint8_t month;
|
||||
+ grub_uint8_t day;
|
||||
+ grub_uint8_t hour;
|
||||
+ grub_uint8_t minute;
|
||||
+ grub_uint8_t second;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+struct pks_signed_var
|
||||
+{
|
||||
+ grub_uint8_t version;
|
||||
+ struct pks_timestamp time;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/* Platform Keystore */
|
||||
+static grub_size_t pks_max_object_size;
|
||||
+grub_uint8_t grub_use_platform_keystore = 0;
|
||||
+grub_pks_t grub_platform_keystore = { .use_static_keys = 0, .db = NULL, .dbx = NULL, .db_entries = 0, .dbx_entries = 0 };
|
||||
+
|
||||
+/* converts the esl data into the ESL */
|
||||
+static grub_esl_t *
|
||||
+grub_convert_to_esl (const grub_uint8_t *esl_data, const grub_size_t esl_data_size)
|
||||
+{
|
||||
+ grub_esl_t *esl = NULL;
|
||||
+
|
||||
+ if (esl_data_size < sizeof (grub_esl_t) || esl_data == NULL)
|
||||
+ return esl;
|
||||
+
|
||||
+ esl = (grub_esl_t *) esl_data;
|
||||
+
|
||||
+ return esl;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * imports the GUID, esd, and its size into the pks sd buffer and
|
||||
+ * pks sd entries from the EFI signature list.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_esd_from_esl (const grub_uint8_t *esl_data, grub_size_t esl_size,
|
||||
+ const grub_size_t signature_size, const grub_uuid_t *guid,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_esd_t *esd = NULL;
|
||||
+ grub_pks_sd_t *signature = *pks_sd;
|
||||
+ grub_size_t entries = *pks_sd_entries;
|
||||
+ grub_size_t data_size = 0, offset = 0;
|
||||
+
|
||||
+ /* reads the esd from esl */
|
||||
+ while (esl_size > 0)
|
||||
+ {
|
||||
+ esd = (grub_esd_t *) (esl_data + offset);
|
||||
+ data_size = signature_size - sizeof (grub_esd_t);
|
||||
+
|
||||
+ if (signature != NULL)
|
||||
+ signature = grub_realloc (signature, (entries + 1) * sizeof (grub_pks_sd_t));
|
||||
+ else
|
||||
+ signature = grub_malloc (sizeof (grub_pks_sd_t));
|
||||
+
|
||||
+ if (signature == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ signature[entries].data = grub_malloc (data_size * sizeof (grub_uint8_t));
|
||||
+ if (signature[entries].data == NULL)
|
||||
+ {
|
||||
+ /*
|
||||
+ * allocated memory will be freed by
|
||||
+ * grub_release_platform_keystore
|
||||
+ */
|
||||
+ *pks_sd = signature;
|
||||
+ *pks_sd_entries = entries + 1;
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+ }
|
||||
+
|
||||
+ grub_memcpy (signature[entries].data, esd->signaturedata, data_size);
|
||||
+ signature[entries].data_size = data_size;
|
||||
+ signature[entries].guid = *guid;
|
||||
+ entries++;
|
||||
+ esl_size -= signature_size;
|
||||
+ offset += signature_size;
|
||||
+ }
|
||||
+
|
||||
+ *pks_sd = signature;
|
||||
+ *pks_sd_entries = entries;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * extracts the esd after removing the esl header from esl.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_esl_to_esd (const grub_uint8_t *esl_data, grub_size_t *next_esl,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_uuid_t guid = { 0 };
|
||||
+ grub_esl_t *esl = NULL;
|
||||
+ grub_size_t offset = 0, esl_size = 0,
|
||||
+ signature_size = 0, signature_header_size = 0;
|
||||
+
|
||||
+ esl = grub_convert_to_esl (esl_data, *next_esl);
|
||||
+ if (esl == NULL)
|
||||
+ return grub_error (GRUB_ERR_BUG, "invalid ESL");
|
||||
+
|
||||
+ esl_size = grub_le_to_cpu32 (esl->signaturelistsize);
|
||||
+ signature_header_size = grub_le_to_cpu32 (esl->signatureheadersize);
|
||||
+ signature_size = grub_le_to_cpu32 (esl->signaturesize);
|
||||
+ guid = esl->signaturetype;
|
||||
+
|
||||
+ if (esl_size < sizeof (grub_esl_t) || esl_size > *next_esl)
|
||||
+ return grub_error (GRUB_ERR_BUG, "invalid ESL size (%u)\n", esl_size);
|
||||
+
|
||||
+ *next_esl = esl_size;
|
||||
+ offset = sizeof (grub_esl_t) + signature_header_size;
|
||||
+ esl_size = esl_size - offset;
|
||||
+
|
||||
+ return grub_esd_from_esl (esl_data + offset, esl_size, signature_size, &guid,
|
||||
+ pks_sd, pks_sd_entries);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * imports the EFI signature data and the number of esd from the esl
|
||||
+ * into the pks sd buffer and pks sd entries.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_pks_sd_from_esl (const grub_uint8_t *esl_data, grub_size_t esl_size,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_size_t next_esl = esl_size;
|
||||
+
|
||||
+ do
|
||||
+ {
|
||||
+ rc = grub_esl_to_esd (esl_data, &next_esl, pks_sd, pks_sd_entries);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ break;
|
||||
+
|
||||
+ esl_data += next_esl;
|
||||
+ esl_size -= next_esl;
|
||||
+ next_esl = esl_size;
|
||||
+ }
|
||||
+ while (esl_size > 0);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * unpacking the signed secure boot variable
|
||||
+ * return error if size too small or version mismatch
|
||||
+ * discards timestamp, only needed in verifying updates
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_unpack_signed_variable (grub_uint8_t *indata, grub_size_t insize,
|
||||
+ grub_uint8_t **data, grub_size_t *size)
|
||||
+{
|
||||
+ struct pks_signed_var *psv = NULL;
|
||||
+
|
||||
+ /* do not permit negative or size 0 data */
|
||||
+ if (insize <= sizeof (struct pks_signed_var))
|
||||
+ return PKS_UNPACK_ERROR;
|
||||
+
|
||||
+ psv = (struct pks_signed_var *) indata;
|
||||
+ if (psv->version != 0)
|
||||
+ return PKS_UNPACK_VERSION_ERROR;
|
||||
+
|
||||
+ *data = indata + sizeof (struct pks_signed_var);
|
||||
+ *size = insize - sizeof (struct pks_signed_var);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * reads the secure boot version from PKS as an object.
|
||||
+ * caller must free result
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_sbversion_from_pks (grub_uint8_t **out, grub_size_t *outlen, grub_size_t *policy)
|
||||
+{
|
||||
+ *out = grub_malloc (pks_max_object_size);
|
||||
+ if (*out == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ return grub_ieee1275_pks_read_object (PKS_CONSUMER_FW, SB_VERSION_KEY_NAME,
|
||||
+ SB_VERSION_KEY_LEN, *out, pks_max_object_size,
|
||||
+ outlen, policy);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * reads the secure boot variable from PKS.
|
||||
+ * caller must free result
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_sbvar_from_pks (const grub_uint8_t sbvarflags, const grub_uint8_t sbvartype,
|
||||
+ grub_uint8_t **out, grub_size_t *outlen)
|
||||
+{
|
||||
+ *out = grub_malloc (pks_max_object_size);
|
||||
+ if (*out == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory");
|
||||
+
|
||||
+ return grub_ieee1275_pks_read_sbvar (sbvarflags, sbvartype, *out,
|
||||
+ pks_max_object_size, outlen);
|
||||
+}
|
||||
+
|
||||
+/* Test the availability of PKS support. */
|
||||
+static grub_err_t
|
||||
+grub_is_support_pks (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_ieee1275_cell_t missing = 0;
|
||||
+
|
||||
+ rc = grub_ieee1275_test ("pks-max-object-size", &missing);
|
||||
+ if (rc != GRUB_ERR_NONE || (int) missing == -1)
|
||||
+ grub_printf ("Warning: doesn't have PKS support!\n");
|
||||
+ else
|
||||
+ {
|
||||
+ rc = grub_ieee1275_pks_max_object_size (&pks_max_object_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_printf ("Warning: PKS support is there but it has zero objects!\n");
|
||||
+ }
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * retrieves the secure boot variable from PKS, unpacks it, reads the esd
|
||||
+ * from ESL, and stores the information in the pks sd buffer.
|
||||
+ */
|
||||
+static grub_err_t
|
||||
+grub_secure_boot_variables (const grub_uint8_t sbvarflags, const grub_uint8_t sbvartype,
|
||||
+ grub_pks_sd_t **pks_sd, grub_size_t *pks_sd_entries)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_uint8_t *data = NULL, *esl_data = NULL;
|
||||
+ grub_size_t data_len = 0, esl_data_size = 0;
|
||||
+
|
||||
+ rc = grub_sbvar_from_pks (sbvarflags, sbvartype, &data, &data_len);
|
||||
+ /*
|
||||
+ * at this point we have SB_VERSION, so any error is worth
|
||||
+ * at least some user-visible info
|
||||
+ */
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ rc = grub_error (rc, "secure boot variable %s reading (%d)",
|
||||
+ (sbvartype == DB ? "db" : "dbx"), rc);
|
||||
+ else
|
||||
+ {
|
||||
+ rc = grub_unpack_signed_variable (data, data_len, &esl_data, &esl_data_size);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ rc = grub_error (rc, "unpacking of signed variable %s structure (%d)",
|
||||
+ (sbvartype == DB ? "db" : "dbx"), rc);
|
||||
+ else
|
||||
+ rc = grub_pks_sd_from_esl ((const grub_uint8_t *) esl_data, esl_data_size,
|
||||
+ pks_sd, pks_sd_entries);
|
||||
+ }
|
||||
+
|
||||
+ grub_free (data);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* reads secure boot version (SB_VERSION) */
|
||||
+static grub_err_t
|
||||
+grub_secure_boot_version (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+ grub_uint8_t *data = NULL;
|
||||
+ grub_size_t len = 0, policy = 0;
|
||||
+
|
||||
+ rc = grub_sbversion_from_pks (&data, &len, &policy);
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_printf ("Warning: SB version read failed! (%d)\n", rc);
|
||||
+ else if (len != 1 || (*data != 1 && *data != 0))
|
||||
+ {
|
||||
+ grub_printf ("Warning: found unexpected SB version! (%d)\n", *data);
|
||||
+ rc = GRUB_ERR_INVALID_COMMAND;
|
||||
+ }
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Warning: switch to static key!\n");
|
||||
+ if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED)
|
||||
+ grub_fatal ("Secure Boot locked down");
|
||||
+ }
|
||||
+ else
|
||||
+ grub_use_platform_keystore = *data;
|
||||
+
|
||||
+ grub_free (data);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/* releasing allocated memory */
|
||||
+void
|
||||
+grub_release_platform_keystore (void)
|
||||
+{
|
||||
+ grub_size_t i = 0;
|
||||
+
|
||||
+ for (i = 0; i < grub_platform_keystore.db_entries; i++)
|
||||
+ grub_free (grub_platform_keystore.db[i].data);
|
||||
+
|
||||
+ for (i = 0; i < grub_platform_keystore.dbx_entries; i++)
|
||||
+ grub_free (grub_platform_keystore.dbx[i].data);
|
||||
+
|
||||
+ grub_free (grub_platform_keystore.db);
|
||||
+ grub_free (grub_platform_keystore.dbx);
|
||||
+ grub_memset (&grub_platform_keystore, 0x00, sizeof (grub_pks_t));
|
||||
+}
|
||||
+
|
||||
+/* initialization of the Platform Keystore */
|
||||
+grub_err_t
|
||||
+grub_platform_keystore_init (void)
|
||||
+{
|
||||
+ grub_err_t rc = GRUB_ERR_NONE;
|
||||
+
|
||||
+ grub_printf ("trying to load Platform Keystore\n");
|
||||
+
|
||||
+ rc = grub_is_support_pks ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_printf ("Warning: switch to static key!\n");
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
+ /* SB_VERSION */
|
||||
+ rc = grub_secure_boot_version ();
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ return rc;
|
||||
+
|
||||
+ if (grub_use_platform_keystore)
|
||||
+ {
|
||||
+ grub_memset (&grub_platform_keystore, 0x00, sizeof (grub_pks_t));
|
||||
+ /* DB */
|
||||
+ rc = grub_secure_boot_variables (0, DB, &grub_platform_keystore.db,
|
||||
+ &grub_platform_keystore.db_entries);
|
||||
+ if ((int)rc == PKS_OBJECT_NOT_FOUND)
|
||||
+ {
|
||||
+ rc = GRUB_ERR_NONE;
|
||||
+ /* DB variable won't be available by default in PKS, So, it will loads the Default Keys from ELF Note */
|
||||
+ grub_platform_keystore.use_static_keys = 1;
|
||||
+ }
|
||||
+
|
||||
+ if (rc == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ /* DBX */
|
||||
+ rc = grub_secure_boot_variables (0, DBX, &grub_platform_keystore.dbx,
|
||||
+ &grub_platform_keystore.dbx_entries);
|
||||
+ if ((int)rc == PKS_OBJECT_NOT_FOUND)
|
||||
+ {
|
||||
+ grub_printf ("Warning: dbx is not found!\n");
|
||||
+ rc = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
+ if (rc != GRUB_ERR_NONE)
|
||||
+ grub_release_platform_keystore ();
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
diff --git a/include/grub/platform_keystore.h b/include/grub/platform_keystore.h
|
||||
new file mode 100644
|
||||
index 000000000..8cc4266c9
|
||||
--- /dev/null
|
||||
+++ b/include/grub/platform_keystore.h
|
||||
@@ -0,0 +1,190 @@
|
||||
+#ifndef __PLATFORM_KEYSTORE_H__
|
||||
+#define __PLATFORM_KEYSTORE_H__
|
||||
+
|
||||
+#include <grub/symbol.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+#if __GNUC__ >= 9
|
||||
+#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
|
||||
+#endif
|
||||
+
|
||||
+#define GRUB_UUID_SIZE 16
|
||||
+#define GRUB_MAX_HASH_SIZE 64
|
||||
+
|
||||
+typedef struct grub_uuid grub_uuid_t;
|
||||
+typedef struct grub_esd grub_esd_t;
|
||||
+typedef struct grub_esl grub_esl_t;
|
||||
+
|
||||
+/* The structure of a UUID.*/
|
||||
+struct grub_uuid
|
||||
+{
|
||||
+ grub_uint8_t b[GRUB_UUID_SIZE];
|
||||
+};
|
||||
+
|
||||
+/* The structure of an EFI signature database (ESD).*/
|
||||
+struct grub_esd
|
||||
+{
|
||||
+ /*
|
||||
+ * An identifier which identifies the agent which added
|
||||
+ * the signature to the list.
|
||||
+ */
|
||||
+ grub_uuid_t signatureowner;
|
||||
+ /* The format of the signature is defined by the SignatureType.*/
|
||||
+ grub_uint8_t signaturedata[];
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/* The structure of an EFI signature list (ESL).*/
|
||||
+struct grub_esl
|
||||
+{
|
||||
+ /* Type of the signature. GUID signature types are defined in below.*/
|
||||
+ grub_uuid_t signaturetype;
|
||||
+ /* Total size of the signature list, including this header.*/
|
||||
+ grub_uint32_t signaturelistsize;
|
||||
+ /*
|
||||
+ * Size of the signature header which precedes
|
||||
+ * the array of signatures.
|
||||
+ */
|
||||
+ grub_uint32_t signatureheadersize;
|
||||
+ /* Size of each signature.*/
|
||||
+ grub_uint32_t signaturesize;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/*
|
||||
+ * The GRUB_PKS_CERT_* is derived from the following files referred from edk2-staging[1] repo
|
||||
+ * of tianocore
|
||||
+ *
|
||||
+ * MdePkg/Include/Guid/ImageAuthentication.h
|
||||
+ *
|
||||
+ * [1] https://github.com/tianocore/edk2-staging
|
||||
+ */
|
||||
+
|
||||
+#define GRUB_PKS_CERT_X509_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, \
|
||||
+ 0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, \
|
||||
+ 0x5c, 0x2b, 0xf0, 0x72 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_SHA1_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x12, 0xa5, 0x6c, 0x82, 0x10, 0xcf, \
|
||||
+ 0xc9, 0x4a, 0xb1, 0x87, 0xbe, 0x1, \
|
||||
+ 0x49, 0x66, 0x31, 0xbd \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_SHA224_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x33, 0x52, 0x6e, 0xb, 0x5c, 0xa6, \
|
||||
+ 0xc9, 0x44, 0x94, 0x7, 0xd9, 0xab, \
|
||||
+ 0x83, 0xbf, 0xc8, 0xbd \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_SHA256_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x26, 0x16, 0xc4, 0xc1, 0x4c, 0x50, \
|
||||
+ 0x92, 0x40, 0xac, 0xa9, 0x41, 0xf9, \
|
||||
+ 0x36, 0x93, 0x43, 0x28 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_SHA384_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x07, 0x53, 0x3e, 0xff, 0xd0, 0x9f, \
|
||||
+ 0xc9, 0x48, 0x85, 0xf1, 0x8a, 0xd5, \
|
||||
+ 0x6c, 0x70, 0x1e, 0x1 \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_SHA512_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0xae, 0x0f, 0x3e, 0x09, 0xc4, 0xa6, \
|
||||
+ 0x50, 0x4f, 0x9f, 0x1b, 0xd4, 0x1e, \
|
||||
+ 0x2b, 0x89, 0xc1, 0x9a \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_X509_SHA256_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x92, 0xa4, 0xd2, 0x3b, 0xc0, 0x96, \
|
||||
+ 0x79, 0x40, 0xb4, 0x20, 0xfc, 0xf9, \
|
||||
+ 0x8e, 0xf1, 0x03, 0xed \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_X509_SHA384_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x6e, 0x87, 0x76, 0x70, 0xc2, 0x80, \
|
||||
+ 0xe6, 0x4e, 0xaa, 0xd2, 0x28, 0xb3, \
|
||||
+ 0x49, 0xa6, 0x86, 0x5b \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_PKS_CERT_X509_SHA512_GUID \
|
||||
+ (grub_uuid_t) \
|
||||
+ { \
|
||||
+ { \
|
||||
+ 0x63, 0xbf, 0x6d, 0x44, 0x02, 0x25, \
|
||||
+ 0xda, 0x4c, 0xbc, 0xfa, 0x24, 0x65, \
|
||||
+ 0xd2, 0xb0, 0xfe, 0x9d \
|
||||
+ } \
|
||||
+ }
|
||||
+
|
||||
+typedef struct grub_pks_sd grub_pks_sd_t;
|
||||
+typedef struct grub_pks grub_pks_t;
|
||||
+
|
||||
+/* The structure of a PKS signature data.*/
|
||||
+struct grub_pks_sd
|
||||
+{
|
||||
+ grub_uuid_t guid; /* signature type */
|
||||
+ grub_uint8_t *data; /* signature data */
|
||||
+ grub_size_t data_size; /* size of signature data */
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/* The structure of a PKS.*/
|
||||
+struct grub_pks
|
||||
+{
|
||||
+ grub_uint8_t use_static_keys;
|
||||
+ grub_pks_sd_t *db; /* signature database */
|
||||
+ grub_pks_sd_t *dbx; /* forbidden signature database */
|
||||
+ grub_size_t db_entries; /* size of signature database */
|
||||
+ grub_size_t dbx_entries; /* size of forbidden signature database */
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+#ifdef __powerpc__
|
||||
+
|
||||
+/* initialization of the Platform Keystore */
|
||||
+grub_err_t grub_platform_keystore_init (void);
|
||||
+/* releasing allocated memory */
|