From e17b63e7f81b6c3eb1c6ec5741f91e05644acef9 Mon Sep 17 00:00:00 2001 From: Lukas Nykryn Date: Thu, 22 Aug 2024 16:56:09 +0200 Subject: [PATCH] systemd-252-44 Resolves: RHEL-50103,RHEL-50651 --- ...tin-net_id-use-firmware_node-sun-for.patch | 152 +++++++++++++++ ...e-constants-for-confidential-virt-de.patch | 184 ++++++++++++++++++ ...PI-for-detecting-confidential-virtua.patch | 168 ++++++++++++++++ ...ernel-cmdline-from-SMBIOS-in-a-confi.patch | 58 ++++++ ...-TDX-confidential-VM-on-Azure-platfo.patch | 121 ++++++++++++ systemd.spec | 14 +- 6 files changed, 696 insertions(+), 1 deletion(-) create mode 100644 1037-Revert-udev-builtin-net_id-use-firmware_node-sun-for.patch create mode 100644 1038-fundamental-share-constants-for-confidential-virt-de.patch create mode 100644 1039-efi-add-helper-API-for-detecting-confidential-virtua.patch create mode 100644 1040-efi-don-t-pull-kernel-cmdline-from-SMBIOS-in-a-confi.patch create mode 100644 1041-Fix-detection-of-TDX-confidential-VM-on-Azure-platfo.patch diff --git a/1037-Revert-udev-builtin-net_id-use-firmware_node-sun-for.patch b/1037-Revert-udev-builtin-net_id-use-firmware_node-sun-for.patch new file mode 100644 index 0000000..3a823b2 --- /dev/null +++ b/1037-Revert-udev-builtin-net_id-use-firmware_node-sun-for.patch @@ -0,0 +1,152 @@ +From ae92c09f0ddfea2ff6042e152eec9af86013da38 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 22 Aug 2024 14:24:42 +0200 +Subject: [PATCH] Revert "udev-builtin-net_id: use firmware_node/sun for + ID_NET_NAME_SLOT" + +This reverts commit 7af151ca282d506a8e409a68b656f6d1cd2f13fb. + +It seems that virtio devices always have "0" in +the firmware_node/sun. And because of that, udev will +always name the device ens0, which leads to collisions. +So let's disable it for now. + +rhel-only: policy + +Reverts: RHEL-50103 +--- + man/systemd.net-naming-scheme.xml | 5 +-- + src/shared/netif-naming-scheme.h | 3 +- + src/udev/udev-builtin-net_id.c | 66 ++++--------------------------- + 3 files changed, 10 insertions(+), 64 deletions(-) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index c9a7e1e493..83293e5636 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -510,10 +510,9 @@ + to distinguish between devices. However, name conflict can occur if these devices are not + children of the same PCI bridge, e.g. there are multiple PCI bridges in the same slot. + +- +- PCI slot number is now read from firmware_node/sun sysfs file. + + ++ + + + By default rhel-9.0 is used. +@@ -667,7 +666,7 @@ ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1 + + + +- PCI Ethernet card in slot with firmware index number ++ PCI Ethernet card in hotplug slot with firmware index number + + # /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1 + ID_NET_NAME_MAC=enx000000000466 +diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h +index b1ac2e4320..5bc071f8db 100644 +--- a/src/shared/netif-naming-scheme.h ++++ b/src/shared/netif-naming-scheme.h +@@ -42,7 +42,6 @@ typedef enum NamingSchemeFlags { + * This is disabled since rhel-9.5, as it seems not to work at least for some setups. See upstream issue #28929. */ + NAMING_DEVICETREE_ALIASES = 1 << 15, /* Generate names from devicetree aliases */ + NAMING_SR_IOV_R = 1 << 17, /* Use "r" suffix for SR-IOV VF representors */ +- NAMING_FIRMWARE_NODE_SUN = 1 << 18, /* Use firmware_node/sun to get PCI slot number */ + + /* And now the masks that combine the features above */ + NAMING_V238 = 0, +@@ -74,7 +73,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_9_2 = NAMING_RHEL_9_0, + NAMING_RHEL_9_3 = NAMING_RHEL_9_0 | NAMING_SR_IOV_R, + NAMING_RHEL_9_4 = NAMING_RHEL_9_3, +- NAMING_RHEL_9_5 = (NAMING_RHEL_9_4 & ~NAMING_BRIDGE_MULTIFUNCTION_SLOT) | NAMING_FIRMWARE_NODE_SUN, ++ NAMING_RHEL_9_5 = NAMING_RHEL_9_4 & ~NAMING_BRIDGE_MULTIFUNCTION_SLOT, + + EXTRA_NET_NAMING_SCHEMES + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index 291fb4ba36..16c9971876 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -442,51 +442,6 @@ static int pci_get_hotplug_slot(sd_device *dev, uint32_t *ret) { + return -ENOENT; + } + +-static int get_device_firmware_node_sun(sd_device *dev, uint32_t *ret) { +- const char *attr; +- int r; +- +- assert(dev); +- assert(ret); +- +- r = device_get_sysattr_value_filtered(dev, "firmware_node/sun", &attr); +- if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to read firmware_node/sun, ignoring: %m"); +- +- r = safe_atou32(attr, ret); +- if (r < 0) +- return log_device_warning_errno(dev, r, "Failed to parse firmware_node/sun '%s', ignoring: %m", attr); +- +- return 0; +-} +- +-static int pci_get_slot_from_firmware_node_sun(sd_device *dev, uint32_t *ret) { +- int r; +- sd_device *slot_dev; +- +- assert(dev); +- assert(ret); +- +- /* Try getting the ACPI _SUN for the device */ +- if (get_device_firmware_node_sun(dev, ret) >= 0) +- return 0; +- +- r = sd_device_get_parent_with_subsystem_devtype(dev, "pci", NULL, &slot_dev); +- if (r < 0) +- return log_device_debug_errno(dev, r, "Failed to find pci parent, ignoring: %m"); +- +- if (is_pci_bridge(slot_dev) && is_pci_multifunction(dev) <= 0) +- return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ESTALE), +- "Not using slot information because the parent pcieport " +- "is a bridge and the PCI device is not multifunction."); +- +- /* Try getting the ACPI _SUN from the parent pcieport */ +- if (get_device_firmware_node_sun(slot_dev, ret) >= 0) +- return 0; +- +- return -ENOENT; +-} +- + static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) { + const char *sysname, *attr; + unsigned domain, bus, slot, func; +@@ -562,20 +517,13 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) { + domain, bus, slot, func, strempty(info->phys_port_name), dev_port, + special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), empty_to_na(names->pci_path)); + +- if (naming_scheme_has(NAMING_FIRMWARE_NODE_SUN)) +- r = pci_get_slot_from_firmware_node_sun(names->pcidev, &hotplug_slot); +- else +- r = -1; +- /* If we don't find a slot using firmware_node/sun, fallback to hotplug_slot */ +- if (r < 0) { +- r = pci_get_hotplug_slot(names->pcidev, &hotplug_slot); +- if (r < 0) +- return r; +- if (r > 0) +- /* If the hotplug slot is found through the function ID, then drop the domain from the name. +- * See comments in parse_hotplug_slot_from_function_id(). */ +- domain = 0; +- } ++ r = pci_get_hotplug_slot(names->pcidev, &hotplug_slot); ++ if (r < 0) ++ return r; ++ if (r > 0) ++ /* If the hotplug slot is found through the function ID, then drop the domain from the name. ++ * See comments in parse_hotplug_slot_from_function_id(). */ ++ domain = 0; + + s = names->pci_slot; + l = sizeof(names->pci_slot); diff --git a/1038-fundamental-share-constants-for-confidential-virt-de.patch b/1038-fundamental-share-constants-for-confidential-virt-de.patch new file mode 100644 index 0000000..ee3c6fa --- /dev/null +++ b/1038-fundamental-share-constants-for-confidential-virt-de.patch @@ -0,0 +1,184 @@ +From 704f06e7ac11b8e6887b617ae5a0d67854a98e2a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Thu, 13 Jul 2023 14:02:33 +0100 +Subject: [PATCH] fundamental: share constants for confidential virt detection +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 129b9e3f42d6a2bd92fa7c78ab08a29d6403ddc8) + +Related: RHEL-50651 +--- + src/basic/confidential-virt.c | 67 +---------------- + .../confidential-virt-fundamental.h | 72 +++++++++++++++++++ + 2 files changed, 73 insertions(+), 66 deletions(-) + create mode 100644 src/fundamental/confidential-virt-fundamental.h + +diff --git a/src/basic/confidential-virt.c b/src/basic/confidential-virt.c +index 746aa8c313..64067098e5 100644 +--- a/src/basic/confidential-virt.c ++++ b/src/basic/confidential-virt.c +@@ -5,10 +5,10 @@ + #endif + #include + #include +-#include + #include + #include + ++#include "confidential-virt-fundamental.h" + #include "confidential-virt.h" + #include "fd-util.h" + #include "fileio.h" +@@ -16,71 +16,6 @@ + #include "string-table.h" + #include "utf8.h" + +-#define CPUID_PROCESSOR_INFO_AND_FEATURE_BITS UINT32_C(0x1) +- +-/* +- * AMD64 Architecture Programmer’s Manual Volume 3: +- * General-Purpose and System Instructions. +- * Chapter: E4.1 - Maximum Extended Function Number and Vendor String +- * https://www.amd.com/system/files/TechDocs/24594.pdf +- */ +-#define CPUID_GET_HIGHEST_FUNCTION UINT32_C(0x80000000) +- +-/* +- * AMD64 Architecture Programmer’s Manual Volume 3: +- * General-Purpose and System Instructions. +- * Chapter: E4.17 - Encrypted Memory Capabilities +- * https://www.amd.com/system/files/TechDocs/24594.pdf +- */ +-#define CPUID_AMD_GET_ENCRYPTED_MEMORY_CAPABILITIES UINT32_C(0x8000001f) +- +-/* +- * AMD64 Architecture Programmer’s Manual Volume 3: +- * General-Purpose and System Instructions. +- * Chapter: 15.34.10 - SEV_STATUS MSR +- * https://www.amd.com/system/files/TechDocs/24593.pdf +- */ +-#define MSR_AMD64_SEV UINT32_C(0xc0010131) +- +-/* +- * Intel® TDX Module v1.5 Base Architecture Specification +- * Chapter: 11.2 +- * https://www.intel.com/content/www/us/en/content-details/733575/intel-tdx-module-v1-5-base-architecture-specification.html +- */ +- +-#define CPUID_INTEL_TDX_ENUMERATION UINT32_C(0x21) +- +-/* Requirements for Implementing the Microsoft Hypervisor Interface +- * https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs +- */ +-#define CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS UINT32_C(0x40000000) +- +-#define CPUID_HYPERV_FEATURES UINT32_C(0x40000003) +- +-#define CPUID_HYPERV_ISOLATION_CONFIG UINT32_C(0x4000000C) +- +-#define CPUID_HYPERV_MIN UINT32_C(0x40000005) +-#define CPUID_HYPERV_MAX UINT32_C(0x4000ffff) +- +-#define CPUID_SIG_AMD "AuthenticAMD" +-#define CPUID_SIG_INTEL "GenuineIntel" +-#define CPUID_SIG_INTEL_TDX "IntelTDX " +-#define CPUID_SIG_HYPERV "Microsoft Hv" +- +-/* ecx bit 31: set => hyperpvisor, unset => bare metal */ +-#define CPUID_FEATURE_HYPERVISOR (UINT32_C(1) << 31) +- +-/* Linux include/asm-generic/hyperv-tlfs.h */ +-#define CPUID_HYPERV_CPU_MANAGEMENT (UINT32_C(1) << 12) /* root partition */ +-#define CPUID_HYPERV_ISOLATION (UINT32_C(1) << 22) /* confidential VM partition */ +- +-#define CPUID_HYPERV_ISOLATION_TYPE_MASK UINT32_C(0xf) +-#define CPUID_HYPERV_ISOLATION_TYPE_SNP 2 +- +-#define EAX_SEV (UINT32_C(1) << 1) +-#define MSR_SEV (UINT64_C(1) << 0) +-#define MSR_SEV_ES (UINT64_C(1) << 1) +-#define MSR_SEV_SNP (UINT64_C(1) << 2) + + #if defined(__x86_64__) + +diff --git a/src/fundamental/confidential-virt-fundamental.h b/src/fundamental/confidential-virt-fundamental.h +new file mode 100644 +index 0000000000..986923e1c2 +--- /dev/null ++++ b/src/fundamental/confidential-virt-fundamental.h +@@ -0,0 +1,72 @@ ++/* SPDX-License-Identifier: LGPL-2.1-or-later */ ++ ++#include ++ ++/* Keep CVM detection logic in this file at feature parity with ++ * that in src/efi/boot/vmm.c */ ++ ++#define CPUID_PROCESSOR_INFO_AND_FEATURE_BITS UINT32_C(0x1) ++ ++/* ++ * AMD64 Architecture Programmer’s Manual Volume 3: ++ * General-Purpose and System Instructions. ++ * Chapter: E4.1 - Maximum Extended Function Number and Vendor String ++ * https://www.amd.com/system/files/TechDocs/24594.pdf ++ */ ++#define CPUID_GET_HIGHEST_FUNCTION UINT32_C(0x80000000) ++ ++/* ++ * AMD64 Architecture Programmer’s Manual Volume 3: ++ * General-Purpose and System Instructions. ++ * Chapter: E4.17 - Encrypted Memory Capabilities ++ * https://www.amd.com/system/files/TechDocs/24594.pdf ++ */ ++#define CPUID_AMD_GET_ENCRYPTED_MEMORY_CAPABILITIES UINT32_C(0x8000001f) ++ ++/* ++ * AMD64 Architecture Programmer’s Manual Volume 3: ++ * General-Purpose and System Instructions. ++ * Chapter: 15.34.10 - SEV_STATUS MSR ++ * https://www.amd.com/system/files/TechDocs/24593.pdf ++ */ ++#define MSR_AMD64_SEV UINT32_C(0xc0010131) ++ ++/* ++ * Intel® TDX Module v1.5 Base Architecture Specification ++ * Chapter: 11.2 ++ * https://www.intel.com/content/www/us/en/content-details/733575/intel-tdx-module-v1-5-base-architecture-specification.html ++ */ ++ ++#define CPUID_INTEL_TDX_ENUMERATION UINT32_C(0x21) ++ ++/* Requirements for Implementing the Microsoft Hypervisor Interface ++ * https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs ++ */ ++#define CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS UINT32_C(0x40000000) ++ ++#define CPUID_HYPERV_FEATURES UINT32_C(0x40000003) ++ ++#define CPUID_HYPERV_ISOLATION_CONFIG UINT32_C(0x4000000C) ++ ++#define CPUID_HYPERV_MIN UINT32_C(0x40000005) ++#define CPUID_HYPERV_MAX UINT32_C(0x4000ffff) ++ ++#define CPUID_SIG_AMD "AuthenticAMD" ++#define CPUID_SIG_INTEL "GenuineIntel" ++#define CPUID_SIG_INTEL_TDX "IntelTDX " ++#define CPUID_SIG_HYPERV "Microsoft Hv" ++ ++/* ecx bit 31: set => hyperpvisor, unset => bare metal */ ++#define CPUID_FEATURE_HYPERVISOR (UINT32_C(1) << 31) ++ ++/* Linux include/asm-generic/hyperv-tlfs.h */ ++#define CPUID_HYPERV_CPU_MANAGEMENT (UINT32_C(1) << 12) /* root partition */ ++#define CPUID_HYPERV_ISOLATION (UINT32_C(1) << 22) /* confidential VM partition */ ++ ++#define CPUID_HYPERV_ISOLATION_TYPE_MASK UINT32_C(0xf) ++#define CPUID_HYPERV_ISOLATION_TYPE_SNP 2 ++ ++#define EAX_SEV (UINT32_C(1) << 1) ++#define MSR_SEV (UINT64_C(1) << 0) ++#define MSR_SEV_ES (UINT64_C(1) << 1) ++#define MSR_SEV_SNP (UINT64_C(1) << 2) diff --git a/1039-efi-add-helper-API-for-detecting-confidential-virtua.patch b/1039-efi-add-helper-API-for-detecting-confidential-virtua.patch new file mode 100644 index 0000000..c940fda --- /dev/null +++ b/1039-efi-add-helper-API-for-detecting-confidential-virtua.patch @@ -0,0 +1,168 @@ +From d8753fd5e71a4be0e99ecbbbfa052cb7bd90d717 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 7 Jul 2023 16:28:19 +0100 +Subject: [PATCH] efi: add helper API for detecting confidential virtualization +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This helper is a simplified version of detect_confidential_virtualization() +that merely returns a boolean status flag reflecting whether we are believed +to be running inside a confidential VM. + +This flag can be used for turning off features that are inappropriate to +use from a CVM, but must not be used for releasing sensitive data. The +latter must only be done in response to an attestation for the environment. + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit b354a2cafc8ea38b4551aa3e4f078f1d7aa40c7c) + +Related: RHEL-50651 +--- + src/boot/efi/vmm.c | 117 +++++++++++++++++++++++++++++++++++++++++++++ + src/boot/efi/vmm.h | 2 + + 2 files changed, 119 insertions(+) + +diff --git a/src/boot/efi/vmm.c b/src/boot/efi/vmm.c +index f9a59dca0a..214f8f7024 100644 +--- a/src/boot/efi/vmm.c ++++ b/src/boot/efi/vmm.c +@@ -7,6 +7,7 @@ + # include + #endif + ++#include "confidential-virt-fundamental.h" + #include "drivers.h" + #include "efi-string.h" + #include "string-util-fundamental.h" +@@ -323,3 +324,119 @@ const char* smbios_find_oem_string(const char *name) { + + return NULL; + } ++ ++#if defined(__i386__) || defined(__x86_64__) ++static uint32_t cpuid_leaf(uint32_t eax, char ret_sig[static 13], bool swapped) { ++ /* zero-init as some queries explicitly require subleaf == 0 */ ++ uint32_t sig[3] = {}; ++ ++ if (swapped) ++ __cpuid_count(eax, 0, eax, sig[0], sig[2], sig[1]); ++ else ++ __cpuid_count(eax, 0, eax, sig[0], sig[1], sig[2]); ++ ++ memcpy(ret_sig, sig, sizeof(sig)); ++ ret_sig[12] = 0; /* \0-terminate the string to make string comparison possible */ ++ ++ return eax; ++} ++ ++static uint64_t msr(uint32_t index) { ++ uint64_t val; ++#ifdef __x86_64__ ++ uint32_t low, high; ++ asm volatile ("rdmsr" : "=a"(low), "=d"(high) : "c"(index) : "memory"); ++ val = ((uint64_t)high << 32) | low; ++#else ++ asm volatile ("rdmsr" : "=A"(val) : "c"(index) : "memory"); ++#endif ++ return val; ++} ++ ++static bool detect_hyperv_sev(void) { ++ uint32_t eax, ebx, ecx, edx, feat; ++ char sig[13] = {}; ++ ++ feat = cpuid_leaf(CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS, sig, false); ++ ++ if (feat < CPUID_HYPERV_MIN || feat > CPUID_HYPERV_MAX) ++ return false; ++ ++ if (memcmp(sig, CPUID_SIG_HYPERV, sizeof(sig)) != 0) ++ return false; ++ ++ __cpuid(CPUID_HYPERV_FEATURES, eax, ebx, ecx, edx); ++ ++ if (ebx & CPUID_HYPERV_ISOLATION && !(ebx & CPUID_HYPERV_CPU_MANAGEMENT)) { ++ __cpuid(CPUID_HYPERV_ISOLATION_CONFIG, eax, ebx, ecx, edx); ++ ++ if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == CPUID_HYPERV_ISOLATION_TYPE_SNP) ++ return true; ++ } ++ ++ return false; ++} ++ ++static bool detect_sev(void) { ++ uint32_t eax, ebx, ecx, edx; ++ uint64_t msrval; ++ ++ __cpuid(CPUID_GET_HIGHEST_FUNCTION, eax, ebx, ecx, edx); ++ ++ if (eax < CPUID_AMD_GET_ENCRYPTED_MEMORY_CAPABILITIES) ++ return false; ++ ++ __cpuid(CPUID_AMD_GET_ENCRYPTED_MEMORY_CAPABILITIES, eax, ebx, ecx, edx); ++ ++ /* bit 1 == CPU supports SEV feature ++ * ++ * Note, Azure blocks this CPUID leaf from its SEV-SNP ++ * guests, so we must fallback to trying some HyperV ++ * specific CPUID checks. ++ */ ++ if (!(eax & EAX_SEV)) ++ return detect_hyperv_sev(); ++ ++ msrval = msr(MSR_AMD64_SEV); ++ ++ if (msrval & (MSR_SEV_SNP | MSR_SEV_ES | MSR_SEV)) ++ return true; ++ ++ return false; ++} ++ ++static bool detect_tdx(void) { ++ uint32_t eax, ebx, ecx, edx; ++ char sig[13] = {}; ++ ++ __cpuid(CPUID_GET_HIGHEST_FUNCTION, eax, ebx, ecx, edx); ++ ++ if (eax < CPUID_INTEL_TDX_ENUMERATION) ++ return false; ++ ++ cpuid_leaf(CPUID_INTEL_TDX_ENUMERATION, sig, true); ++ ++ if (memcmp(sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0) ++ return true; ++ ++ return false; ++} ++#endif /* ! __i386__ && ! __x86_64__ */ ++ ++bool is_confidential_vm(void) { ++#if defined(__i386__) || defined(__x86_64__) ++ char sig[13] = {}; ++ ++ if (!cpuid_in_hypervisor()) ++ return false; ++ ++ cpuid_leaf(0, sig, true); ++ ++ if (memcmp(sig, CPUID_SIG_AMD, sizeof(sig)) == 0) ++ return detect_sev(); ++ if (memcmp(sig, CPUID_SIG_INTEL, sizeof(sig)) == 0) ++ return detect_tdx(); ++#endif /* ! __i386__ && ! __x86_64__ */ ++ ++ return false; ++} +diff --git a/src/boot/efi/vmm.h b/src/boot/efi/vmm.h +index 2002f32bec..55c12039d2 100644 +--- a/src/boot/efi/vmm.h ++++ b/src/boot/efi/vmm.h +@@ -9,4 +9,6 @@ EFI_STATUS vmm_open(EFI_HANDLE *ret_qemu_dev, EFI_FILE **ret_qemu_dir); + + bool in_hypervisor(void); + ++bool is_confidential_vm(void); ++ + const char* smbios_find_oem_string(const char *name); diff --git a/1040-efi-don-t-pull-kernel-cmdline-from-SMBIOS-in-a-confi.patch b/1040-efi-don-t-pull-kernel-cmdline-from-SMBIOS-in-a-confi.patch new file mode 100644 index 0000000..d9d161a --- /dev/null +++ b/1040-efi-don-t-pull-kernel-cmdline-from-SMBIOS-in-a-confi.patch @@ -0,0 +1,58 @@ +From 23d58876e6301dd33f0f039a2cacb95a340dc2ea Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 7 Jul 2023 16:30:20 +0100 +Subject: [PATCH] efi: don't pull kernel cmdline from SMBIOS in a confidential + VM +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +In a confidential VM, the SMBIOS data is not trusted, as it is under the +control of the host OS/admin and not covered by attestation of the machine. + +Fixes: https://github.com/systemd/systemd/issues/27604 +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 4b1153cfcc397df5a095f2ec7e587787e8ba47ee) + +Related: RHEL-50651 +--- + src/boot/efi/stub.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c +index 2c7c56de3e..93843f015a 100644 +--- a/src/boot/efi/stub.c ++++ b/src/boot/efi/stub.c +@@ -494,17 +494,21 @@ static EFI_STATUS real_main(EFI_HANDLE image) { + log_error_status(err, "Error loading UKI-specific addons, ignoring: %m"); + parameters_measured = parameters_measured < 0 ? m : (parameters_measured && m); + +- const char *extra = smbios_find_oem_string("io.systemd.stub.kernel-cmdline-extra"); +- if (extra) { +- _cleanup_free_ char16_t *tmp = TAKE_PTR(cmdline), *extra16 = xstr8_to_16(extra); +- cmdline = xasprintf("%ls %ls", tmp, extra16); +- +- /* SMBIOS strings are measured in PCR1, but we also want to measure them in our specific +- * PCR12, as firmware-owned PCRs are very difficult to use as they'll contain unpredictable +- * measurements that are not under control of the machine owner. */ +- m = false; +- (void) tpm_log_load_options(extra16, &m); +- parameters_measured = parameters_measured < 0 ? m : (parameters_measured && m); ++ /* SMBIOS OEM Strings data is controlled by the host admin and not covered ++ * by the VM attestation, so MUST NOT be trusted when in a confidential VM */ ++ if (!is_confidential_vm()) { ++ const char *extra = smbios_find_oem_string("io.systemd.stub.kernel-cmdline-extra"); ++ if (extra) { ++ _cleanup_free_ char16_t *tmp = TAKE_PTR(cmdline), *extra16 = xstr8_to_16(extra); ++ cmdline = xasprintf("%ls %ls", tmp, extra16); ++ ++ /* SMBIOS strings are measured in PCR1, but we also want to measure them in our specific ++ * PCR12, as firmware-owned PCRs are very difficult to use as they'll contain unpredictable ++ * measurements that are not under control of the machine owner. */ ++ m = false; ++ (void) tpm_log_load_options(extra16, &m); ++ parameters_measured = parameters_measured < 0 ? m : (parameters_measured && m); ++ } + } + + export_variables(loaded_image); diff --git a/1041-Fix-detection-of-TDX-confidential-VM-on-Azure-platfo.patch b/1041-Fix-detection-of-TDX-confidential-VM-on-Azure-platfo.patch new file mode 100644 index 0000000..a53b1e1 --- /dev/null +++ b/1041-Fix-detection-of-TDX-confidential-VM-on-Azure-platfo.patch @@ -0,0 +1,121 @@ +From adb6c21257cf8b077e8d55c3326549a671a70481 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Tue, 30 Jul 2024 10:51:21 +0100 +Subject: [PATCH] Fix detection of TDX confidential VM on Azure platform +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The original CVM detection logic for TDX assumes that the guest can see +the standard TDX CPUID leaf. This was true in Azure when this code was +originally written, however, current Azure now blocks that leaf in the +paravisor. Instead it is required to use the same Azure specific CPUID +leaf that is used for SEV-SNP detection, which reports the VM isolation +type. + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 9d7be044cad1ae54e344daf8f2ec37da46faf0fd) + +Related: RHEL-50651 +--- + src/basic/confidential-virt.c | 11 ++++++++--- + src/boot/efi/vmm.c | 9 ++++++--- + src/fundamental/confidential-virt-fundamental.h | 1 + + 3 files changed, 15 insertions(+), 6 deletions(-) + +diff --git a/src/basic/confidential-virt.c b/src/basic/confidential-virt.c +index 64067098e5..0929e0e745 100644 +--- a/src/basic/confidential-virt.c ++++ b/src/basic/confidential-virt.c +@@ -77,7 +77,7 @@ static uint64_t msr(uint64_t index) { + return ret; + } + +-static bool detect_hyperv_sev(void) { ++static bool detect_hyperv_cvm(uint32_t isoltype) { + uint32_t eax, ebx, ecx, edx, feat; + char sig[13] = {}; + +@@ -101,7 +101,7 @@ static bool detect_hyperv_sev(void) { + ebx = ecx = edx = 0; + cpuid(&eax, &ebx, &ecx, &edx); + +- if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == CPUID_HYPERV_ISOLATION_TYPE_SNP) ++ if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == isoltype) + return true; + } + +@@ -134,7 +134,7 @@ static ConfidentialVirtualization detect_sev(void) { + if (!(eax & EAX_SEV)) { + log_debug("No sev in CPUID, trying hyperv CPUID"); + +- if (detect_hyperv_sev()) ++ if (detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_SNP)) + return CONFIDENTIAL_VIRTUALIZATION_SEV_SNP; + + log_debug("No hyperv CPUID"); +@@ -172,6 +172,11 @@ static ConfidentialVirtualization detect_tdx(void) { + if (memcmp(sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0) + return CONFIDENTIAL_VIRTUALIZATION_TDX; + ++ log_debug("No tdx in CPUID, trying hyperv CPUID"); ++ ++ if (detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_TDX)) ++ return CONFIDENTIAL_VIRTUALIZATION_TDX; ++ + return CONFIDENTIAL_VIRTUALIZATION_NONE; + } + +diff --git a/src/boot/efi/vmm.c b/src/boot/efi/vmm.c +index 214f8f7024..153cafba4e 100644 +--- a/src/boot/efi/vmm.c ++++ b/src/boot/efi/vmm.c +@@ -353,7 +353,7 @@ static uint64_t msr(uint32_t index) { + return val; + } + +-static bool detect_hyperv_sev(void) { ++static bool detect_hyperv_cvm(uint32_t isoltype) { + uint32_t eax, ebx, ecx, edx, feat; + char sig[13] = {}; + +@@ -370,7 +370,7 @@ static bool detect_hyperv_sev(void) { + if (ebx & CPUID_HYPERV_ISOLATION && !(ebx & CPUID_HYPERV_CPU_MANAGEMENT)) { + __cpuid(CPUID_HYPERV_ISOLATION_CONFIG, eax, ebx, ecx, edx); + +- if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == CPUID_HYPERV_ISOLATION_TYPE_SNP) ++ if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == isoltype) + return true; + } + +@@ -395,7 +395,7 @@ static bool detect_sev(void) { + * specific CPUID checks. + */ + if (!(eax & EAX_SEV)) +- return detect_hyperv_sev(); ++ return detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_SNP); + + msrval = msr(MSR_AMD64_SEV); + +@@ -419,6 +419,9 @@ static bool detect_tdx(void) { + if (memcmp(sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0) + return true; + ++ if (detect_hyperv_cvm(CPUID_HYPERV_ISOLATION_TYPE_TDX)) ++ return true; ++ + return false; + } + #endif /* ! __i386__ && ! __x86_64__ */ +diff --git a/src/fundamental/confidential-virt-fundamental.h b/src/fundamental/confidential-virt-fundamental.h +index 986923e1c2..618b5800ea 100644 +--- a/src/fundamental/confidential-virt-fundamental.h ++++ b/src/fundamental/confidential-virt-fundamental.h +@@ -65,6 +65,7 @@ + + #define CPUID_HYPERV_ISOLATION_TYPE_MASK UINT32_C(0xf) + #define CPUID_HYPERV_ISOLATION_TYPE_SNP 2 ++#define CPUID_HYPERV_ISOLATION_TYPE_TDX 3 + + #define EAX_SEV (UINT32_C(1) << 1) + #define MSR_SEV (UINT64_C(1) << 0) diff --git a/systemd.spec b/systemd.spec index c256ef7..04a6d11 100644 --- a/systemd.spec +++ b/systemd.spec @@ -25,7 +25,7 @@ Name: systemd Url: https://systemd.io Version: 252 -Release: 43%{?dist} +Release: 44%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -1125,6 +1125,11 @@ Patch1033: 1033-udev-add-conf-virt-constant-for-confidential-virtual.patch Patch1034: 1034-confidential-virt-split-caching-of-CVM-detection-int.patch Patch1035: 1035-confidential-virt-add-detection-for-s390x-target.patch Patch1036: 1036-man-systemd-detect-virt-list-known-CVM-technologies.patch +Patch1037: 1037-Revert-udev-builtin-net_id-use-firmware_node-sun-for.patch +Patch1038: 1038-fundamental-share-constants-for-confidential-virt-de.patch +Patch1039: 1039-efi-add-helper-API-for-detecting-confidential-virtua.patch +Patch1040: 1040-efi-don-t-pull-kernel-cmdline-from-SMBIOS-in-a-confi.patch +Patch1041: 1041-Fix-detection-of-TDX-confidential-VM-on-Azure-platfo.patch # Downstream-only patches (9000–9999) @@ -2007,6 +2012,13 @@ systemd-hwdb update &>/dev/null || : %{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/* %changelog +* Thu Aug 22 2024 systemd maintenance team - 252-44 +- Revert "udev-builtin-net_id: use firmware_node/sun for ID_NET_NAME_SLOT" (RHEL-50103) +- fundamental: share constants for confidential virt detection (RHEL-50651) +- efi: add helper API for detecting confidential virtualization (RHEL-50651) +- efi: don't pull kernel cmdline from SMBIOS in a confidential VM (RHEL-50651) +- Fix detection of TDX confidential VM on Azure platform (RHEL-50651) + * Thu Aug 22 2024 systemd maintenance team - 252-43 - udev-builtin-net_id: skip non-directory entry earlier (RHEL-50103) - udev-builtin-net_id: return earlier when hotplug slot is not found (RHEL-50103)