5
0
mirror of git://git.proxmox.com/git/qemu-server.git synced 2025-01-24 02:04:10 +03:00

Verify VM-specific CPU configs seperately

$cpu_fmt is being reused for custom CPUs as well as VM-specific CPU
settings. The "pve-vm-cpu-conf" format is introduced to verify a config
specifically for use as VM-specific settings.

"pve-cpu-conf" is registered for use in custom CPU API calls (where no
additional checks are required).

Signed-off-by: Stefan Reiter <s.reiter@proxmox.com>
This commit is contained in:
Stefan Reiter 2020-02-12 16:11:23 +01:00 committed by Thomas Lamprecht
parent b3e894883a
commit 5d008ad383
2 changed files with 69 additions and 6 deletions

View File

@ -545,7 +545,7 @@ EODESCR
optional => 1,
description => "Emulated CPU type.",
type => 'string',
format => $PVE::QemuServer::CPUConfig::cpu_fmt,
format => 'pve-vm-cpu-conf',
},
parent => get_standard_option('pve-snapshot-name', {
optional => 1,

View File

@ -103,9 +103,10 @@ my @supported_cpu_flags = (
'hv-evmcs',
'aes'
);
my $cpu_flag = qr/[+-](@{[join('|', @supported_cpu_flags)]})/;
my $cpu_flag_supported_re = qr/([+-])(@{[join('|', @supported_cpu_flags)]})/;
my $cpu_flag_any_re = qr/([+-])([a-zA-Z0-9\-_\.]+)/;
our $cpu_fmt = {
my $cpu_fmt = {
cputype => {
description => "Emulated CPU type. Can be default or custom name (custom model names must be prefixed with 'custom-').",
type => 'string',
@ -138,14 +139,76 @@ our $cpu_fmt = {
flags => {
description => "List of additional CPU flags separated by ';'."
. " Use '+FLAG' to enable, '-FLAG' to disable a flag."
. " Currently supported flags: @{[join(', ', @supported_cpu_flags)]}.",
. " Custom CPU models can specify any flag supported by"
. " QEMU/KVM, VM-specific flags must be from the following"
. " set for security reasons: @{[join(', ', @supported_cpu_flags)]}.",
format_description => '+FLAG[;-FLAG...]',
type => 'string',
pattern => qr/$cpu_flag(;$cpu_flag)*/,
pattern => qr/$cpu_flag_any_re(;$cpu_flag_any_re)*/,
optional => 1,
},
};
# $cpu_fmt describes both the CPU config passed as part of a VM config, as well
# as the definition of a custom CPU model. There are some slight differences
# though, which we catch in the custom verification function below.
PVE::JSONSchema::register_format('pve-cpu-conf', \&parse_cpu_conf_basic);
sub parse_cpu_conf_basic {
my ($cpu_str, $noerr) = @_;
my $cpu = eval { PVE::JSONSchema::parse_property_string($cpu_fmt, $cpu_str) };
if ($@) {
die $@ if !$noerr;
return undef;
}
# required, but can't be forced in schema since it's encoded in section
# header for custom models
if (!$cpu->{cputype}) {
die "CPU is missing cputype\n" if !$noerr;
return undef;
}
return $cpu;
}
PVE::JSONSchema::register_format('pve-vm-cpu-conf', \&parse_vm_cpu_conf);
sub parse_vm_cpu_conf {
my ($cpu_str, $noerr) = @_;
my $cpu = parse_cpu_conf_basic($cpu_str, $noerr);
return undef if !$cpu;
my $cputype = $cpu->{cputype};
# a VM-specific config is only valid if the cputype exists
if (is_custom_model($cputype)) {
eval { get_custom_model($cputype); };
if ($@) {
die $@ if !$noerr;
return undef;
}
} else {
if (!defined($cpu_vendor_list->{$cputype})) {
die "Built-in cputype '$cputype' is not defined (missing 'custom-' prefix?)\n" if !$noerr;
return undef;
}
}
# in a VM-specific config, certain properties are limited/forbidden
if ($cpu->{flags} && $cpu->{flags} !~ m/$cpu_flag_supported_re(;$cpu_flag_supported_re)*/) {
die "VM-specific CPU flags must be a subset of: @{[join(', ', @supported_cpu_flags)]}\n"
if !$noerr;
return undef;
}
die "Property 'reported-model' not allowed in VM-specific CPU config.\n"
if defined($cpu->{'reported-model'});
return $cpu;
}
# Section config settings
my $defaultData = {
# shallow copy, since SectionConfig modifies propertyList internally
@ -235,7 +298,7 @@ sub print_cpu_device {
my $kvm = $conf->{kvm} // 1;
my $cpu = $kvm ? "kvm64" : "qemu64";
if (my $cputype = $conf->{cpu}) {
my $cpuconf = PVE::JSONSchema::parse_property_string($cpu_fmt, $cputype)
my $cpuconf = parse_cpu_conf_basic($cputype)
or die "Cannot parse cpu description: $cputype\n";
$cpu = $cpuconf->{cputype};