You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
6.4 KiB
118 lines
6.4 KiB
6 months ago
|
From 36e71ba28d490bb3dba34df8eef472c1560e3772 Mon Sep 17 00:00:00 2001
|
||
|
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||
|
Date: Thu, 17 Nov 2022 16:11:44 +0100
|
||
|
Subject: [PATCH] bootctl: install system token on virtualized systems
|
||
|
|
||
|
Removing the virtualization check might not be the worst thing in the
|
||
|
world, and would potentially get many, many more systems properly seeded
|
||
|
rather than not seeded. There are a few reasons to consider this:
|
||
|
|
||
|
- In most QEMU setups and most guides on how to setup QEMU, a separate
|
||
|
pflash file is used for nvram variables, and this generally isn't
|
||
|
copied around.
|
||
|
|
||
|
- We're now hashing in a timestamp, which should provide some level of
|
||
|
differentiation, given that EFI_TIME has a nanoseconds field.
|
||
|
|
||
|
- The kernel itself will additionally hash in: a high resolution time
|
||
|
stamp, a cycle counter, RDRAND output, the VMGENID uniquely
|
||
|
identifying the virtual machine, any other seeds from the hypervisor
|
||
|
(like from FDT or setup_data).
|
||
|
|
||
|
- During early boot, the RNG is reseeded quite frequently to account for
|
||
|
the importance of early differentiation.
|
||
|
|
||
|
So maybe the mitigating factors make the actual feared problem
|
||
|
significantly less likely and therefore the pros of having file-based
|
||
|
seeding might outweigh the cons of weird misconfigured setups having a
|
||
|
hypothetical problem on first boot.
|
||
|
|
||
|
(cherry picked from commit a4eea6038c1c7f88adc6d6584d18ea60ea11b08f)
|
||
|
|
||
|
Related: RHEL-16952
|
||
|
---
|
||
|
docs/RANDOM_SEEDS.md | 15 ++++-----------
|
||
|
src/boot/bootctl.c | 20 --------------------
|
||
|
units/systemd-boot-system-token.service | 8 ++------
|
||
|
3 files changed, 6 insertions(+), 37 deletions(-)
|
||
|
|
||
|
diff --git a/docs/RANDOM_SEEDS.md b/docs/RANDOM_SEEDS.md
|
||
|
index b7240f0d89..a1134d6417 100644
|
||
|
--- a/docs/RANDOM_SEEDS.md
|
||
|
+++ b/docs/RANDOM_SEEDS.md
|
||
|
@@ -232,17 +232,10 @@ boot, in order to ensure the entropy pool is filled up quickly.
|
||
|
too), which should be safe even with FAT file system drivers built into
|
||
|
low-quality EFI firmwares.
|
||
|
|
||
|
- As a special restriction: in virtualized environments PID 1 will refrain
|
||
|
- from using this mechanism, for safety reasons. This is because on VM
|
||
|
- environments the EFI variable space and the disk space is generally not
|
||
|
- maintained physically separate (for example, `qemu` in EFI mode stores the
|
||
|
- variables in the ESP itself). The robustness towards sloppy OS image
|
||
|
- generation is the main purpose of maintaining the 'system token' however,
|
||
|
- and if the EFI variable storage is not kept physically separate from the OS
|
||
|
- image there's no point in it. That said, OS builders that know that they are
|
||
|
- not going to replicate the built image on multiple systems may opt to turn
|
||
|
- off the 'system token' concept by setting `random-seed-mode always` in the
|
||
|
- ESP's
|
||
|
+ If the system token is not desired but this seeding mechanism still is, OS
|
||
|
+ builders that know that they are not going to replicate the built image on
|
||
|
+ multiple systems may opt to turn off the 'system token' concept by setting
|
||
|
+ `random-seed-mode always` in the ESP's
|
||
|
[`/loader/loader.conf`](https://www.freedesktop.org/software/systemd/man/loader.conf.html)
|
||
|
file. If done, `systemd-boot` will use the random seed file even if no
|
||
|
system token is found in EFI variables.
|
||
|
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
||
|
index 8d45e11c2b..d495c72bdd 100644
|
||
|
--- a/src/boot/bootctl.c
|
||
|
+++ b/src/boot/bootctl.c
|
||
|
@@ -2048,26 +2048,6 @@ static int install_random_seed(const char *esp) {
|
||
|
if (r < 0) {
|
||
|
if (r != -ENXIO)
|
||
|
log_warning_errno(r, "Failed to parse $SYSTEMD_WRITE_SYSTEM_TOKEN, ignoring.");
|
||
|
-
|
||
|
- if (detect_vm() > 0) {
|
||
|
- /* Let's not write a system token if we detect we are running in a VM
|
||
|
- * environment. Why? Our default security model for the random seed uses the system
|
||
|
- * token as a mechanism to ensure we are not vulnerable to golden master sloppiness
|
||
|
- * issues, i.e. that people initialize the random seed file, then copy the image to
|
||
|
- * many systems and end up with the same random seed in each that is assumed to be
|
||
|
- * valid but in reality is the same for all machines. By storing a system token in
|
||
|
- * the EFI variable space we can make sure that even though the random seeds on disk
|
||
|
- * are all the same they will be different on each system under the assumption that
|
||
|
- * the EFI variable space is maintained separate from the random seed storage. That
|
||
|
- * is generally the case on physical systems, as the ESP is stored on persistent
|
||
|
- * storage, and the EFI variables in NVRAM. However in virtualized environments this
|
||
|
- * is generally not true: the EFI variable set is typically stored along with the
|
||
|
- * disk image itself. For example, using the OVMF EFI firmware the EFI variables are
|
||
|
- * stored in a file in the ESP itself. */
|
||
|
-
|
||
|
- log_notice("Not installing system token, since we are running in a virtualized environment.");
|
||
|
- return 0;
|
||
|
- }
|
||
|
} else if (r == 0) {
|
||
|
log_notice("Not writing system token, because $SYSTEMD_WRITE_SYSTEM_TOKEN is set to false.");
|
||
|
return 0;
|
||
|
diff --git a/units/systemd-boot-system-token.service b/units/systemd-boot-system-token.service
|
||
|
index 5a56d7c331..689b902000 100644
|
||
|
--- a/units/systemd-boot-system-token.service
|
||
|
+++ b/units/systemd-boot-system-token.service
|
||
|
@@ -16,15 +16,11 @@ After=local-fs.target systemd-random-seed.service
|
||
|
Conflicts=shutdown.target initrd-switch-root.target
|
||
|
Before=shutdown.target initrd-switch-root.target
|
||
|
|
||
|
-# Don't run this in a VM environment, because there EFI variables are not
|
||
|
-# actually stored in NVRAM, independent of regular storage.
|
||
|
-ConditionVirtualization=no
|
||
|
-
|
||
|
# Only run this if the boot loader can support random seed initialization.
|
||
|
ConditionPathExists=/sys/firmware/efi/efivars/LoaderFeatures-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
|
||
|
|
||
|
-# Only run this if there is no system token defined yet, or …
|
||
|
-ConditionPathExists=|!/sys/firmware/efi/efivars/LoaderSystemToken-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
|
||
|
+# Only run this if there is no system token defined yet
|
||
|
+ConditionPathExists=!/sys/firmware/efi/efivars/LoaderSystemToken-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
|
||
|
|
||
|
[Service]
|
||
|
Type=oneshot
|