[pve-devel] [PATCH qemu-server v3 11/11] let VirtIO RNG devices source entropy from mapped HWRNGs
Fabian Grünbichler
f.gruenbichler at proxmox.com
Tue Feb 11 13:34:52 CET 2025
On February 10, 2025 4:37 pm, Filip Schauer wrote:
> 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.schauer at 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 at pam';
> }
> + } elsif ($device->{mapping}) {
> + $rpcenv->check_full($user, "/mapping/hwrng/$device->{mapping}", ['Mapping.Use']);
> + } else {
> + die "either 'source' or 'mapping' must be set.\n";
this is handled here, but if both are set then the parser will silently
drop them (see below).. seems a bit inconsistent, for other mappings the
parser enforces this already as well..
> }
> }
> }
> 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
this cannot really happen, since the parser already dropped this
combination?
>
> 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};
should we maybe simplify this - and just defined a single static mapping
for now for /dev/hwrng, so that we have an ACL path to refer to?
> }
>
> return;
> --
> 2.39.5
>
>
>
> _______________________________________________
> pve-devel mailing list
> pve-devel at lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
>
>
>
More information about the pve-devel
mailing list