[pve-devel] [PATCH v2 qemu-server 1/6] api: check Sys.Audit permissions when setting a custom CPU model

Stefan Reiter s.reiter at proxmox.com
Mon May 4 12:58:38 CEST 2020


Explicitly allows changing other properties than the cputype, even if
the currently set cputype is not accessible by the user. This way, an
administrator can assign a custom CPU type to a VM for a less privileged
user without breaking edit functionality for them.

Signed-off-by: Stefan Reiter <s.reiter at proxmox.com>
---
 PVE/API2/Qemu.pm | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 7ffc538..4cf0a11 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -21,6 +21,7 @@ use PVE::GuestHelpers;
 use PVE::QemuConfig;
 use PVE::QemuServer;
 use PVE::QemuServer::Drive;
+use PVE::QemuServer::CPUConfig;
 use PVE::QemuServer::Monitor qw(mon_cmd);
 use PVE::QemuMigrate;
 use PVE::RPCEnvironment;
@@ -236,6 +237,26 @@ my $create_disks = sub {
     return $vollist;
 };
 
+my $check_cpu_model_access = sub {
+    my ($rpcenv, $authuser, $new, $existing) = @_;
+
+    return if !defined($new->{cpu});
+
+    my $cpu = PVE::JSONSchema::check_format('pve-vm-cpu-conf', $new->{cpu});
+    return if !$cpu || !$cpu->{cputype}; # always allow default
+    my $cputype = $cpu->{cputype};
+
+    if ($existing && $existing->{cpu}) {
+	# changing only other settings doesn't require permissions for CPU model
+	my $existingCpu = PVE::JSONSchema::check_format('pve-vm-cpu-conf', $existing->{cpu});
+	return if $existingCpu->{cputype} eq $cputype;
+    }
+
+    if (PVE::QemuServer::CPUConfig::is_custom_model($cputype)) {
+	$rpcenv->check($authuser, "/nodes", ['Sys.Audit']);
+    }
+};
+
 my $cpuoptions = {
     'cores' => 1,
     'cpu' => 1,
@@ -543,6 +564,8 @@ __PACKAGE__->register_method({
 
 	    &$check_vm_modify_config_perm($rpcenv, $authuser, $vmid, $pool, [ keys %$param]);
 
+	    &$check_cpu_model_access($rpcenv, $authuser, $param);
+
 	    foreach my $opt (keys %$param) {
 		if (PVE::QemuServer::is_valid_drivename($opt)) {
 		    my $drive = PVE::QemuServer::parse_drive($opt, $param->{$opt});
@@ -1122,6 +1145,8 @@ my $update_vm_api  = sub {
 	die "checksum missmatch (file change by other user?)\n"
 	    if $digest && $digest ne $conf->{digest};
 
+	&$check_cpu_model_access($rpcenv, $authuser, $param, $conf);
+
 	# FIXME: 'suspended' lock should probabyl be a state or "weak" lock?!
 	if (scalar(@delete) && grep { $_ eq 'vmstate'} @delete) {
 	    if (defined($conf->{lock}) && $conf->{lock} eq 'suspended') {
-- 
2.20.1





More information about the pve-devel mailing list