|
| 1 | +From 3ae6e04ef40dd5d1916dda95334e3278dd23494b Mon Sep 17 00:00:00 2001 |
| 2 | +From: Ben Cressey < [email protected]> |
| 3 | +Date: Tue, 4 Nov 2025 17:53:03 +0000 |
| 4 | +Subject: [PATCH] Hard-code BOOT_IMAGE on kernel command line |
| 5 | + |
| 6 | +GRUB sets the first argument (argv[0]) for the kernel to: |
| 7 | + BOOT_IMAGE=(hdX,gptY)/vmlinuz |
| 8 | + |
| 9 | +For variants that do not support in-place updates, "gptY" will always |
| 10 | +be "gpt3", the first boot partition. However, "hdX" is unpredictable |
| 11 | +and may change depending on how disks are enumerated by the firmware, |
| 12 | +which makes the kernel command line measured into PCR 9 unpredictable |
| 13 | +in turn. |
| 14 | + |
| 15 | +Hard-code argv[0] to the following predictable value: |
| 16 | + BOOT_IMAGE=/vmlinuz |
| 17 | + |
| 18 | +The actual partition selected is still implicitly part of the kernel |
| 19 | +command line, since the dm-mod.create argument includes $boot_uuid to |
| 20 | +pass offsets to the root filesystem and hash tree: |
| 21 | + dm-mod.create=" ... PARTUUID=$boot_uuid/PARTNROFF=1 PARTUUID=$boot_uuid/PARTNROFF=2 ..." |
| 22 | + |
| 23 | +For variants that support in-place updates, it's not possible to |
| 24 | +predict PCR 9 because the kernel and userspace that occupy the first |
| 25 | +and second partition banks may change over time because of updates. |
| 26 | + |
| 27 | +Signed-off-by: Ben Cressey < [email protected]> |
| 28 | +--- |
| 29 | + grub-core/loader/arm64/linux.c | 8 ++++---- |
| 30 | + grub-core/loader/i386/efi/linux.c | 8 ++++---- |
| 31 | + grub-core/loader/i386/linux.c | 10 ++++------ |
| 32 | + include/grub/lib/cmdline.h | 1 + |
| 33 | + 4 files changed, 13 insertions(+), 14 deletions(-) |
| 34 | + |
| 35 | +diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c |
| 36 | +index 419f2201d..a4877b35f 100644 |
| 37 | +--- a/grub-core/loader/arm64/linux.c |
| 38 | ++++ b/grub-core/loader/arm64/linux.c |
| 39 | +@@ -419,16 +419,16 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
| 40 | + grub_free(kernel); |
| 41 | + kernel = NULL; |
| 42 | + |
| 43 | +- cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); |
| 44 | ++ cmdline_size = grub_loader_cmdline_size (argc - 1, argv + 1) + sizeof (LINUX_IMAGE_FULL); |
| 45 | + linux_args = grub_malloc (cmdline_size); |
| 46 | + if (!linux_args) |
| 47 | + { |
| 48 | + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); |
| 49 | + goto fail; |
| 50 | + } |
| 51 | +- grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); |
| 52 | +- err = grub_create_loader_cmdline (argc, argv, |
| 53 | +- linux_args + sizeof (LINUX_IMAGE) - 1, |
| 54 | ++ grub_memcpy (linux_args, LINUX_IMAGE_FULL, sizeof (LINUX_IMAGE_FULL)); |
| 55 | ++ err = grub_create_loader_cmdline (argc - 1, argv + 1, |
| 56 | ++ linux_args + sizeof (LINUX_IMAGE_FULL) - 1, |
| 57 | + cmdline_size, |
| 58 | + GRUB_VERIFY_KERNEL_CMDLINE); |
| 59 | + if (err) |
| 60 | +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c |
| 61 | +index 33a7e8860..fe3714896 100644 |
| 62 | +--- a/grub-core/loader/i386/efi/linux.c |
| 63 | ++++ b/grub-core/loader/i386/efi/linux.c |
| 64 | +@@ -489,10 +489,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
| 65 | + goto fail; |
| 66 | + grub_dprintf ("linux", "cmdline = %p\n", cmdline); |
| 67 | + |
| 68 | +- grub_memcpy (cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); |
| 69 | +- grub_create_loader_cmdline (argc, argv, |
| 70 | +- cmdline + sizeof (LINUX_IMAGE) - 1, |
| 71 | +- lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1), |
| 72 | ++ grub_memcpy (cmdline, LINUX_IMAGE_FULL, sizeof (LINUX_IMAGE_FULL)); |
| 73 | ++ grub_create_loader_cmdline (argc - 1, argv + 1, |
| 74 | ++ cmdline + sizeof (LINUX_IMAGE_FULL) - 1, |
| 75 | ++ lh->cmdline_size - (sizeof (LINUX_IMAGE_FULL) - 1), |
| 76 | + GRUB_VERIFY_KERNEL_CMDLINE); |
| 77 | + |
| 78 | + grub_dprintf ("linux", "cmdline:%s\n", cmdline); |
| 79 | +diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c |
| 80 | +index 3c1ff6476..2061dcc51 100644 |
| 81 | +--- a/grub-core/loader/i386/linux.c |
| 82 | ++++ b/grub-core/loader/i386/linux.c |
| 83 | +@@ -1010,14 +1010,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), |
| 84 | + linux_cmdline = grub_zalloc (maximal_cmdline_size + 1); |
| 85 | + if (!linux_cmdline) |
| 86 | + goto fail; |
| 87 | +- grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); |
| 88 | ++ grub_memcpy (linux_cmdline, LINUX_IMAGE_FULL, sizeof (LINUX_IMAGE_FULL)); |
| 89 | + { |
| 90 | + grub_err_t err; |
| 91 | +- err = grub_create_loader_cmdline (argc, argv, |
| 92 | +- linux_cmdline |
| 93 | +- + sizeof (LINUX_IMAGE) - 1, |
| 94 | +- maximal_cmdline_size |
| 95 | +- - (sizeof (LINUX_IMAGE) - 1), |
| 96 | ++ err = grub_create_loader_cmdline (argc - 1, argv + 1, |
| 97 | ++ linux_cmdline + sizeof (LINUX_IMAGE_FULL) - 1, |
| 98 | ++ maximal_cmdline_size - (sizeof (LINUX_IMAGE_FULL) - 1), |
| 99 | + GRUB_VERIFY_KERNEL_CMDLINE); |
| 100 | + if (err) |
| 101 | + goto fail; |
| 102 | +diff --git a/include/grub/lib/cmdline.h b/include/grub/lib/cmdline.h |
| 103 | +index cdca09b7a..256d665d1 100644 |
| 104 | +--- a/include/grub/lib/cmdline.h |
| 105 | ++++ b/include/grub/lib/cmdline.h |
| 106 | +@@ -24,6 +24,7 @@ |
| 107 | + #include <grub/verify.h> |
| 108 | + |
| 109 | + #define LINUX_IMAGE "BOOT_IMAGE=" |
| 110 | ++#define LINUX_IMAGE_FULL LINUX_IMAGE "/vmlinuz " |
| 111 | + |
| 112 | + unsigned int grub_loader_cmdline_size (int argc, char *argv[]); |
| 113 | + grub_err_t grub_create_loader_cmdline (int argc, char *argv[], char *buf, |
0 commit comments