From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 0764D1FF15C for ; Fri, 14 Nov 2025 02:18:29 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id CD5F733EF; Fri, 14 Nov 2025 02:19:21 +0100 (CET) Message-ID: <5ce79121-9ce3-4f6f-9842-3c9a5572b99b@proxmox.com> Date: Fri, 14 Nov 2025 02:18:47 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Beta To: Proxmox VE development discussion , Fiona Ebner References: <20251111135808.110791-1-f.ebner@proxmox.com> <20251111135808.110791-3-f.ebner@proxmox.com> Content-Language: en-US From: Thomas Lamprecht In-Reply-To: <20251111135808.110791-3-f.ebner@proxmox.com> X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1763083100967 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.025 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [ovmf.pm, qemuserver.pm, drive.pm] Subject: Re: [pve-devel] [PATCH qemu-server 2/2] fix #6985: ovmf: auto-enroll Microsoft UEFI CA 2023 for Windows X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" Am 11.11.25 um 14:57 schrieb Fiona Ebner: > Microsoft's UEFI CA 2011 will expire in June 2026. It's necessary to > ensure that the new UEFI CA 2023 is enrolled for Windows to keep > updates working. > > pve-edk2-firmware >= 4.2025.05-1 includes the 2023 certificate > already, so new disks are fine. Still, check during EFI disk creation > what is actually there, since there is no guarantee that a new enough > version of pve-edk2-firmware is installed. > > A new 'ms-cert' drive property for EFI disks records the year of the > last known-to-be-enrolled MS UEFI CA. This avoids the need to re-check > every time if the 2023 certificate needs to be enrolled. The downside > is that this breaks backwards migration, because a disk with an > unknown option is dropped from the configuration. > > Enrollment and checking for existing disks is done via virt-fw-vars, > which is a new dependency recorded in d/control. While virt-fw-vars > supports raw and qcow2 files out of the box, this is not enough, > because EFI disks can also be vmdk formatted and there are also > storages that use a protocol path like 'rbd://' or 'iscsi://' for > QEMU, which virt-fw-vars cannot handle. Thus, use a FUSE export to > cover all cases. > > Signed-off-by: Fiona Ebner > --- > debian/control | 1 + > src/PVE/QemuServer.pm | 20 +++++++++++++ > src/PVE/QemuServer/Drive.pm | 9 ++++++ > src/PVE/QemuServer/OVMF.pm | 59 +++++++++++++++++++++++++++++++++++++ > 4 files changed, 89 insertions(+) > needs a rebase (or I fumbled something). > diff --git a/debian/control b/debian/control > index 5ac6b0fc..661ac65b 100644 > --- a/debian/control > +++ b/debian/control > @@ -58,6 +58,7 @@ Depends: conntrack, > pve-firewall (>= 6.0.3), > pve-ha-manager (>= 5.0.3), > pve-qemu-kvm (>= 7.1~), > + python3-virt-firmware, > socat, > swtpm, > swtpm-tools, > diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm > index 79ff637a..74836833 100644 > --- a/src/PVE/QemuServer.pm > +++ b/src/PVE/QemuServer.pm > @@ -5373,6 +5373,24 @@ my sub remove_left_over_vmstate_opts { > PVE::QemuConfig->write_config($vmid, $conf) if $found; > } > > +my sub check_efi_vars { > + my ($storecfg, $vmid, $conf) = @_; > + > + return if PVE::QemuConfig->is_template($conf); > + return if !$conf->{efidisk0}; > + return if $conf->{ostype} ne 'win10' && $conf->{ostype} ne 'win11'; > + > + if ( > + my $updated = PVE::QemuServer::OVMF::ensure_ms_2023_cert_enrolled( > + $storecfg, $vmid, $conf->{efidisk0}, > + ) > + ) { > + $conf->{efidisk0} = $updated; > + PVE::QemuConfig->write_config($vmid, $conf); > + } > + return; > +} > + > # see vm_start_nolock for parameters, additionally: > # migrate_opts: > # storagemap = parsed storage map for allocating NBD disks > @@ -5548,6 +5566,8 @@ sub vm_start_nolock { > # With -blockdev, it is necessary to activate the volumes before generating the command line > PVE::Storage::activate_volumes($storecfg, $vollist); > > + check_efi_vars($storecfg, $vmid, $conf) if $conf->{bios} && $conf->{bios} eq 'ovmf'; > + > # Note that for certain cases like templates, the configuration is minimized, so need to ensure > # the rest of the function here uses the same configuration that was used to build the command > ($cmd, $spice_port, my $pci_devices, $conf) = config_to_command( > diff --git a/src/PVE/QemuServer/Drive.pm b/src/PVE/QemuServer/Drive.pm > index f54f9612..c772c803 100644 > --- a/src/PVE/QemuServer/Drive.pm > +++ b/src/PVE/QemuServer/Drive.pm > @@ -521,6 +521,15 @@ my %efitype_fmt = ( > optional => 1, > default => 0, > }, > + 'ms-cert' => { > + type => 'string', > + enum => [qw(2011 2023)], > + description => > + "Informational marker indicating the version of the latest Microsof UEFI certificate" > + . " that has been enrolled by Proxmox VE.", > + optional => 1, > + default => '2011', > + }, > ); > > my $efidisk_fmt = { > diff --git a/src/PVE/QemuServer/OVMF.pm b/src/PVE/QemuServer/OVMF.pm > index 08134e30..badacf54 100644 > --- a/src/PVE/QemuServer/OVMF.pm > +++ b/src/PVE/QemuServer/OVMF.pm > @@ -11,7 +11,9 @@ use PVE::Tools; > > use PVE::QemuServer::Blockdev; > use PVE::QemuServer::Drive qw(checked_volume_format parse_drive print_drive); > +use PVE::QemuServer::Helpers; > use PVE::QemuServer::QemuImage; > +use PVE::QemuServer::QSD; > > my $EDK2_FW_BASE = '/usr/share/pve-edk2-firmware/'; > my $OVMF = { > @@ -128,6 +130,30 @@ sub get_efivars_size { > return -s $ovmf_vars; > } > > +my sub is_ms_2023_cert_enrolled { > + my ($path) = @_; > + > + my $inside_db_section; > + my $found_ms_2023_cert; > + > + my $detect_ms_2023_cert = sub { > + my ($line) = @_; > + return if $found_ms_2023_cert; > + $inside_db_section = undef if !$line; > + $found_ms_2023_cert = 1 > + if $inside_db_section && $line =~ m/CN=Microsoft UEFI CA 2023/; > + $inside_db_section = 1 if $line =~ m/^name=db guid=guid:EfiImageSecurityDatabase/; > + return; > + }; > + > + PVE::Tools::run_command( > + ['virt-fw-vars', '--input', $path, '--print', '--verbose'], > + outfunc => $detect_ms_2023_cert, > + ); > + > + return $found_ms_2023_cert; > +} > + > sub create_efidisk($$$$$$$$) { > my ($storecfg, $storeid, $vmid, $fmt, $arch, $efidisk, $smm, $amd_sev_type) = @_; > > @@ -141,6 +167,10 @@ sub create_efidisk($$$$$$$$) { > PVE::QemuServer::QemuImage::convert($ovmf_vars, $volid, $vars_size_b); > my $size = PVE::Storage::volume_size_info($storecfg, $volid, 3); > > + if ($efidisk->{'pre-enrolled-keys'} && is_ms_2023_cert_enrolled($ovmf_vars)) { > + $efidisk->{'ms-cert'} = '2023' > + } > + > return ($volid, $size / 1024); > } > > @@ -235,4 +265,33 @@ sub print_ovmf_commandline { > return ($cmd, $machine_flags); > } > > +sub ensure_ms_2023_cert_enrolled { > + my ($storecfg, $vmid, $efidisk_str) = @_; > + > + my $efidisk = parse_drive('efidisk0', $efidisk_str); > + return if !$efidisk->{'pre-enrolled-keys'}; > + return if $efidisk->{'ms-cert'} && $efidisk->{'ms-cert'} eq '2023'; > + > + print "efidisk0: enrolling Microsoft UEFI CA 2023\n"; > + > + my $new_qsd = !PVE::QemuServer::Helpers::qsd_running_locally($vmid); > + PVE::QemuServer::QSD::start($vmid) if $new_qsd; > + > + eval { > + my $efi_vars_path = > + PVE::QemuServer::QSD::add_fuse_export($vmid, $efidisk, 'efidisk0-enroll'); > + PVE::Tools::run_command( > + ['virt-fw-vars', '--inplace', $efi_vars_path, '--distro-keys', 'ms-uefi']); > + PVE::QemuServer::QSD::remove_fuse_export($vmid, 'efidisk0-enroll'); > + }; > + my $err = $@; > + > + PVE::QemuServer::QSD::quit($vmid) if $new_qsd; if other request start using this QSD after it was started here they might get interrupted? Albeit currently this is probably rather theoretically due to QSD being per-vmid and we the operations QSD is used as of now are not really being able to run concurently for a single VM FWICT. Might be still good to at least add a comment for this for the case that QSD gets adopted more. > + > + die "efidisk0: enrolling Microsoft UEFI CA 2023 failed - $err" if $err; > + > + $efidisk->{'ms-cert'} = '2023'; > + return print_drive($efidisk); > +} > + > 1; _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel