From 36e71ba28d490bb3dba34df8eef472c1560e3772 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" 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