From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 1DD2A1FF09B for ; Mon, 28 Sep 2026 07:49:12 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id A03112175E; Mon, 28 Sep 2026 07:48:41 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=genua.de; s=202307; t=1790574485; bh=zL9S5t573WgYEy32KZhWUxuxyGynz7srJIGh6sKSw5o=; h=Date:From:To:Subject:References:In-Reply-To:From; b=wl9a3eLzbsrkisxmNtaboZtVyyksxJ+BInGzowIGrmvJnzjPqWNIm2l5XrsWHK/V/ Np3DwaAdr0bzgxN2jVIU6OnIjTOecp8iB6uhMcTtc02IRvm1DgtGpTJLb732uBwaAP MPNOMKbHT1bLtjKMgZyQQiVOJgY1fn2B1WC3BGoasXASJZgDEuMpp0DkoHSK7OTp0Z 8fM7lri0B1pMtdcQYf2SdTVTzg8Fe6anDxbaQUjA/LcqtK1Win/VVLzJ36yCOfXkM1 zdJaNmkZIFfZR9wgkjBdFMsaljJlY1MLEn4LJ8vs3iFqPN/z8RmIiGTXuK6HJtojmL 3Sx+PbR9u3MPg== Date: Mon, 28 Sep 2026 07:48:01 +0200 From: Christian Ludwig To: Subject: [PATCH v2 pve-storage 4/16] api: status: support efi-firmware in upload and download-url Message-ID: <62b59850da5ca40be46662b94e10d5499e615c04.1790337423.git@genua.de> References: MIME-Version: 1.0 In-Reply-To: X-Originating-IP: [192.168.217.185] X-ClientProxiedBy: kch1-mta09.win.genua.de (10.208.16.109) 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.088 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: PQTQJYVR5SSHX5ZI3MTV3BYF5234SJBI X-Message-ID-Hash: PQTQJYVR5SSHX5ZI3MTV3BYF5234SJBI 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 and reject file names outside the safe character class. Signed-off-by: Christian Ludwig --- src/PVE/API2/Storage/Status.pm | 14 ++++++++++++-- src/PVE/Storage.pm | 18 ++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/PVE/API2/Storage/Status.pm b/src/PVE/API2/Storage/Status.pm index 741d514..a6fc317 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,11 @@ __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}+$!) { + raise_param_exc({ filename => "invalid file name" }); + } + $path = PVE::Storage::get_efi_firmware_dir($cfg, $storage); } else { raise_param_exc({ content => "upload content type '$content' not allowed" }); } @@ -770,7 +775,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 +864,11 @@ __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}+$!) { + raise_param_exc({ filename => "invalid file name" }); + } + $path = PVE::Storage::get_efi_firmware_dir($cfg, $storage); } else { raise_param_exc({ content => "upload content-type '$content' is not allowed" }); } diff --git a/src/PVE/Storage.pm b/src/PVE/Storage.pm index 64ea9da..112a828 100755 --- a/src/PVE/Storage.pm +++ b/src/PVE/Storage.pm @@ -555,6 +555,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) = @_; @@ -629,7 +638,12 @@ sub check_volume_access { return if $rpcenv->check($user, "/storage/$sid", ['Datastore.Allocate'], 1); - if ($vtype eq 'iso' || $vtype eq 'vztmpl' || $vtype eq 'import') { + if ( + $vtype eq 'iso' + || $vtype eq 'vztmpl' + || $vtype eq 'import' + || $vtype eq 'efi-firmware' + ) { # require at least read access to storage, (custom) templates/ISOs could be sensitive $rpcenv->check_any( $user, @@ -1297,7 +1311,7 @@ sub template_list { sub volume_list { my ($cfg, $storeid, $vmid, $content) = @_; - my @ctypes = qw(rootdir images vztmpl iso backup snippets import); + my @ctypes = qw(rootdir images vztmpl iso backup snippets import efi-firmware); my $cts = $content ? [$content] : [@ctypes]; -- 2.34.1