This allows a user with the Mapping.Modify privilege on /mapping/hwrng to configure a hardware RNG mapping. A less privileged user with the Mapping.Use privilege can then pass the mapped hardware RNG device as an entropy source to a VirtIO RNG device.
Signed-off-by: Filip Schauer <f.scha...@proxmox.com> --- PVE/API2/Qemu.pm | 5 +++++ PVE/QemuServer.pm | 5 +++++ PVE/QemuServer/RNG.pm | 25 +++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 194e6357..33b3625b 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -812,9 +812,14 @@ my sub check_rng_perm { my $device = PVE::JSONSchema::parse_property_string('pve-qm-rng', $value); if ($device->{source}) { + # Backward compatibility for non-mapped /dev/hwrng if ($device->{source} eq '/dev/hwrng') { die "only root can set '$opt' config for a non-mapped Hardware RNG device\n"; } + } elsif ($device->{mapping}) { + $rpcenv->check_full($authuser, "/mapping/hwrng/$device->{mapping}", ['Mapping.Use']); + } else { + die "either 'source' or 'mapping' must be set.\n"; } return 1; diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index cc69eeb1..82a6c65d 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -6402,10 +6402,15 @@ sub check_mapping_access { my $device = PVE::JSONSchema::parse_property_string('pve-qm-rng', $conf->{$opt}); if ($device->{source}) { + # Backward compatibility for non-mapped /dev/hwrng if ($device->{source} eq '/dev/hwrng') { die "only root can set '$opt' config for a non-mapped Hardware RNG device\n" if $user ne 'root@pam'; } + } elsif ($device->{mapping}) { + $rpcenv->check_full($user, "/mapping/hwrng/$device->{mapping}", ['Mapping.Use']); + } else { + die "either 'source' or 'mapping' must be set.\n"; } } } diff --git a/PVE/QemuServer/RNG.pm b/PVE/QemuServer/RNG.pm index ae5b2530..3ee19852 100644 --- a/PVE/QemuServer/RNG.pm +++ b/PVE/QemuServer/RNG.pm @@ -4,6 +4,7 @@ use strict; use warnings; use PVE::JSONSchema; +use PVE::Mapping::HWRNG; use PVE::Tools qw(file_read_firstline); use PVE::QemuServer::PCI qw(print_pci_addr); @@ -22,11 +23,20 @@ my $rng_fmt = { type => 'string', enum => ['/dev/urandom', '/dev/random', '/dev/hwrng'], default_key => 1, + optional => 1, description => "The file on the host to gather entropy from. Using urandom does *not*" ." decrease security in any meaningful way, as it's still seeded from real entropy, and" ." the bytes provided will most likely be mixed with real entropy on the guest as well." ." '/dev/hwrng' can be used to pass through a hardware RNG from the host.", }, + mapping => { + optional => 1, + type => 'string', + format_description => 'mapping-id', + format => 'pve-configid', + description => "The ID of a cluster wide mapping. When specified, entropy is gathered from" + ." a hardware RNG on the host. Either this or the default-key 'source' must be set.", + }, max_bytes => { type => 'integer', description => "Maximum bytes of entropy allowed to get injected into the guest every" @@ -65,6 +75,11 @@ sub parse_rng { my $res = eval { PVE::JSONSchema::parse_property_string($rng_fmt, $value) }; warn $@ if $@; + my $source = $res->{source}; + my $mapping = $res->{mapping}; + + return if $source && $mapping; # not a valid configuration + return $res; } @@ -89,9 +104,19 @@ sub get_rng_source_path { my ($rng) = @_; my $source = $rng->{source}; + my $mapping = $rng->{mapping}; + + return if $source && $mapping; # not a valid configuration if (defined($source)) { return $source; + } elsif (defined($mapping)) { + my $devices = PVE::Mapping::HWRNG::find_on_current_node($mapping); + die "Hardware RNG mapping not found for '$mapping'\n" if !$devices || !scalar($devices->@*); + die "More than one Hardware RNG mapping per host not supported\n" + if scalar($devices->@*) > 1; + + return $devices->[0]->{path}; } return; -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel