From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [IPv6:2a0f:8001:1:32::40]) by lore.proxmox.com (Postfix) with ESMTPS id A09DB1FF0B0 for ; Tue, 27 Oct 2026 11:13:21 +0100 (CET) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id C010521731; Tue, 27 Oct 2026 11:12:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=genua.de; s=202307; t=1793095935; bh=IlYvqz9Gqv7sGtob0KTEnhUG24tSdnTrD8FPUtNqzpE=; h=Date:From:To:Subject:References:In-Reply-To:From; b=XTO3osKIEiKhFWLWGSn5itPqSx0Kk5futJ78+FLlFZWc5lORR1zS3SCVko/5rr05J V3bslC8hETMGEJ8Rok7F7b9N76fQCQQNgWEgnWdANcAh2iab0xtXZ2BGUBT/FYtdXY VNwwGlBeJ5wv24QOfHQWIJN2HaNPW4lqsvk086lykH0Te9mgEpdj8jJNMeNJgDsQvI raKRpJFwhQw6TgSEgbYaOudpYhyMHXgqqkwGUq0TBY1TSTHPnNLYaQoEbwI8914lbq n3BF78O8XR+Gn9XankQu+TGxgFHYb1e/jWZgRRuEs0/P5dycw9mEmUdY7Vd7js7eeZ zKVgkzVyyKtLQ== Date: Tue, 27 Oct 2026 11:12:14 +0100 From: Christian Ludwig To: Subject: [PATCH pve-storage v3 05/19] api: status: support efi-firmware in upload and download-url Message-ID: <67761df7a5e0682b2e7bfe2025ddc291953f2b18.1793029144.git@genua.de> References: MIME-Version: 1.0 In-Reply-To: X-Originating-IP: [192.168.217.185] X-ClientProxiedBy: kch1-mta07.win.genua.de (10.208.16.107) To kch1-mta07.win.genua.de (10.208.16.107) Content-Type: text/plain; charset="us-ascii" Content-Disposition: inline X-SPAM-LEVEL: Spam detection results: 0 AWL 0.070 Adjusted score from AWL reputation of From: address DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain DMARC_PASS -0.1 DMARC pass policy SPF_HELO_PASS -0.001 SPF: HELO matches SPF record SPF_PASS -0.001 SPF: sender matches SPF record UNPARSEABLE_RELAY 0.001 Informational: message has unparseable relay lines Message-ID-Hash: AFPLWDS6EG4D3GK63FJ3VY6KMSBWIBUD X-Message-ID-Hash: AFPLWDS6EG4D3GK63FJ3VY6KMSBWIBUD X-MailFrom: christian_ludwig@genua.de X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Allow the content type in both endpoints. File names must consist of the safe character class and end with '.fd'. Validate the image after the transfer, like for other content types, and reject anything that is not detected as a raw image. Signed-off-by: Christian Ludwig --- src/PVE/API2/Storage/Status.pm | 22 ++++++++++++++++++++-- src/PVE/Storage.pm | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/PVE/API2/Storage/Status.pm b/src/PVE/API2/Storage/Status.pm index 741d514..fd91639 100644 --- a/src/PVE/API2/Storage/Status.pm +++ b/src/PVE/API2/Storage/Status.pm @@ -533,7 +533,7 @@ __PACKAGE__->register_method({ description => "Content type.", type => 'string', format => 'pve-storage-content', - enum => ['iso', 'vztmpl', 'import'], + enum => ['iso', 'vztmpl', 'import', 'efi-firmware'], }, filename => { description => @@ -618,6 +618,13 @@ __PACKAGE__->register_method({ } $path = PVE::Storage::get_import_dir($cfg, $storage); + } elsif ($content eq 'efi-firmware') { + if ($filename !~ + m!^${PVE::Storage::SAFE_CHAR_CLASS_RE}+$PVE::Storage::EFI_FIRMWARE_EXT_RE_1$! + ) { + raise_param_exc({ filename => "invalid filename or wrong extension" }); + } + $path = PVE::Storage::get_efi_firmware_dir($cfg, $storage); } else { raise_param_exc({ content => "upload content type '$content' not allowed" }); } @@ -693,6 +700,8 @@ __PACKAGE__->register_method({ if ($content eq 'iso') { PVE::Storage::assert_iso_content($tmpfilename); + } elsif ($content eq 'efi-firmware') { + PVE::Storage::assert_efi_firmware_content($tmpfilename); } if ($is_ova) { @@ -770,7 +779,7 @@ __PACKAGE__->register_method({ description => "Content type.", # TODO: could be optional & detected in most cases type => 'string', format => 'pve-storage-content', - enum => ['iso', 'vztmpl', 'import'], + enum => ['iso', 'vztmpl', 'import', 'efi-firmware'], }, filename => { description => @@ -859,6 +868,13 @@ __PACKAGE__->register_method({ } $path = PVE::Storage::get_import_dir($cfg, $storage); + } elsif ($content eq 'efi-firmware') { + if ($filename !~ + m!^${PVE::Storage::SAFE_CHAR_CLASS_RE}+$PVE::Storage::EFI_FIRMWARE_EXT_RE_1$! + ) { + raise_param_exc({ filename => "invalid filename or wrong extension" }); + } + $path = PVE::Storage::get_efi_firmware_dir($cfg, $storage); } else { raise_param_exc({ content => "upload content-type '$content' is not allowed" }); } @@ -885,6 +901,8 @@ __PACKAGE__->register_method({ if ($content eq 'iso') { PVE::Storage::assert_iso_content($tmp_path); + } elsif ($content eq 'efi-firmware') { + PVE::Storage::assert_efi_firmware_content($tmp_path); } if ($is_ova) { diff --git a/src/PVE/Storage.pm b/src/PVE/Storage.pm index 03ec6a1..fb37bdb 100755 --- a/src/PVE/Storage.pm +++ b/src/PVE/Storage.pm @@ -557,6 +557,15 @@ sub get_iso_dir { return $plugin->get_subdir($scfg, 'iso'); } +sub get_efi_firmware_dir { + my ($cfg, $storeid) = @_; + + my $scfg = storage_config($cfg, $storeid); + my $plugin = PVE::Storage::Plugin->lookup($scfg->{type}); + + return $plugin->get_subdir($scfg, 'efi-firmware'); +} + sub get_import_dir { my ($cfg, $storeid) = @_; @@ -2514,4 +2523,14 @@ sub assert_iso_content { return 1; } +sub assert_efi_firmware_content { + my ($path) = @_; + + my (undef, $format) = file_size_info($path, 10, 'auto-detect', 1); + die "efi-firmware image is not in raw format, detected '" . ($format // 'unknown') . "'\n" + if !defined($format) || $format ne 'raw'; + + return 1; +} + 1; -- 2.34.1