all lists on lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user
@ 2025-01-29 15:53 Filip Schauer
  2025-01-29 15:53 ` [pve-devel] [PATCH guest-common v2 1/9] mapping: add a hardware RNG mapping config Filip Schauer
                   ` (9 more replies)
  0 siblings, 10 replies; 15+ messages in thread
From: Filip Schauer @ 2025-01-29 15:53 UTC (permalink / raw)
  To: pve-devel

Allow users with the VM.Config.HWType privilege to configure VirtIO RNG
devices on VMs with either /dev/urandom or /dev/random as the entropy
source.

Further introduce hardware RNG device mapping to be able to selectively
allow non-root users with the Mapping.Use privilege to configure
hardware RNG devices as entropy sources.

Changes since v1:
* Restrict use of /dev/hwrng to the root user
* introduce hardware RNG mapping

pve-guest-common:

Filip Schauer (1):
  mapping: add a hardware RNG mapping config

 src/Makefile             |   1 +
 src/PVE/Mapping/HWRNG.pm | 147 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 148 insertions(+)
 create mode 100644 src/PVE/Mapping/HWRNG.pm


pve-cluster:

Filip Schauer (1):
  cfs: add 'mapping/hwrng.cfg' to observed files

 src/PVE/Cluster.pm  | 1 +
 src/pmxcfs/status.c | 1 +
 2 files changed, 2 insertions(+)


pve-manager:

Filip Schauer (4):
  introduce hardware rng mapping api
  introduce hardware rng scanning api
  ui: add hardware RNG resource mapping
  ui: allow use of mapped hardware RNGs as entropy sources for VMs

 PVE/API2/Cluster/Mapping.pm           |   7 +
 PVE/API2/Cluster/Mapping/HWRNG.pm     | 286 ++++++++++++++++++++++++++
 PVE/API2/Cluster/Mapping/Makefile     |   5 +-
 PVE/API2/Hardware.pm                  |   7 +
 PVE/API2/Hardware/HWRNG.pm            |  47 +++++
 PVE/API2/Hardware/Makefile            |   1 +
 www/manager6/Makefile                 |   3 +
 www/manager6/data/PermPathStore.js    |   1 +
 www/manager6/dc/Config.js             |  10 +
 www/manager6/dc/HWRNGMapView.js       |  76 +++++++
 www/manager6/form/HWRNGMapSelector.js |  99 +++++++++
 www/manager6/qemu/HardwareView.js     |   9 +-
 www/manager6/qemu/RNGEdit.js          |  79 ++++---
 www/manager6/window/HWRNGMapEdit.js   | 149 ++++++++++++++
 14 files changed, 748 insertions(+), 31 deletions(-)
 create mode 100644 PVE/API2/Cluster/Mapping/HWRNG.pm
 create mode 100644 PVE/API2/Hardware/HWRNG.pm
 create mode 100644 www/manager6/dc/HWRNGMapView.js
 create mode 100644 www/manager6/form/HWRNGMapSelector.js
 create mode 100644 www/manager6/window/HWRNGMapEdit.js


qemu-server:

Filip Schauer (3):
  refactor: move rng related code into its own module
  allow non-root users to set /dev/u?random as an RNG source
  let VirtIO RNG devices source entropy from mapped HWRNGs

 PVE/API2/Qemu.pm        |  47 ++++++++++++
 PVE/QemuServer.pm       | 101 +++++++-------------------
 PVE/QemuServer/Makefile |   1 +
 PVE/QemuServer/RNG.pm   | 156 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 229 insertions(+), 76 deletions(-)
 create mode 100644 PVE/QemuServer/RNG.pm


Summary over all repositories:
  22 files changed, 1127 insertions(+), 107 deletions(-)

-- 
Generated by git-murpp 0.6.0


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [pve-devel] [PATCH guest-common v2 1/9] mapping: add a hardware RNG mapping config
  2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
@ 2025-01-29 15:53 ` Filip Schauer
  2025-01-30 12:18   ` Fiona Ebner
  2025-01-29 15:53 ` [pve-devel] [PATCH cluster v2 2/9] cfs: add 'mapping/hwrng.cfg' to observed files Filip Schauer
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Filip Schauer @ 2025-01-29 15:53 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
 src/Makefile             |   1 +
 src/PVE/Mapping/HWRNG.pm | 147 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 148 insertions(+)
 create mode 100644 src/PVE/Mapping/HWRNG.pm

diff --git a/src/Makefile b/src/Makefile
index cbc40c1..ae62b7d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -15,6 +15,7 @@ install: PVE
 	install -m 0644 PVE/StorageTunnel.pm ${PERL5DIR}/PVE/
 	install -m 0644 PVE/Tunnel.pm ${PERL5DIR}/PVE/
 	install -d ${PERL5DIR}/PVE/Mapping
+	install -m 0644 PVE/Mapping/HWRNG.pm ${PERL5DIR}/PVE/Mapping/
 	install -m 0644 PVE/Mapping/PCI.pm ${PERL5DIR}/PVE/Mapping/
 	install -m 0644 PVE/Mapping/USB.pm ${PERL5DIR}/PVE/Mapping/
 	install -d ${PERL5DIR}/PVE/VZDump
diff --git a/src/PVE/Mapping/HWRNG.pm b/src/PVE/Mapping/HWRNG.pm
new file mode 100644
index 0000000..fb9fa8c
--- /dev/null
+++ b/src/PVE/Mapping/HWRNG.pm
@@ -0,0 +1,147 @@
+package PVE::Mapping::HWRNG;
+
+use strict;
+use warnings;
+
+use PVE::Cluster qw(
+    cfs_lock_file
+    cfs_read_file
+    cfs_register_file
+    cfs_write_file
+);
+use PVE::INotify ();
+use PVE::JSONSchema qw(get_standard_option parse_property_string);
+
+use base qw(PVE::SectionConfig);
+
+my $FILENAME = 'mapping/hwrng.cfg';
+
+cfs_register_file($FILENAME,
+		  sub { __PACKAGE__->parse_config(@_); },
+		  sub { __PACKAGE__->write_config(@_); });
+
+
+# so we don't have to repeat the type every time
+sub parse_section_header {
+    my ($class, $line) = @_;
+
+    if ($line =~ m/^(\S+)\s*$/) {
+	my $id = $1;
+	my $errmsg = undef; # set if you want to skip whole section
+	eval { PVE::JSONSchema::pve_verify_configid($id) };
+	$errmsg = $@ if $@;
+	my $config = {}; # to return additional attributes
+	return ('hwrng', $id, $errmsg, $config);
+    }
+    return undef;
+}
+
+sub format_section_header {
+    my ($class, $type, $sectionId, $scfg, $done_hash) = @_;
+
+    return "$sectionId\n";
+}
+
+sub type {
+    return 'hwrng';
+}
+
+my $map_fmt = {
+    node => get_standard_option('pve-node'),
+    path => {
+	description => "The path to the device node of the entropy source.",
+	type => 'string',
+	pattern => qr/^\/dev\/.+$/,
+    },
+    description => {
+	description => "Description of the node specific device.",
+	type => 'string',
+	optional => 1,
+	maxLength => 4096,
+    },
+};
+
+my $defaultData = {
+    propertyList => {
+	id => {
+	    type => 'string',
+	    description => "The ID of the logical HWRNG mapping.",
+	    format => 'pve-configid',
+	},
+	description => {
+	    description => "Description of the logical HWRNG device.",
+	    type => 'string',
+	    optional => 1,
+	    maxLength => 4096,
+	},
+	map => {
+	    type => 'array',
+	    description => 'A list of maps for the cluster nodes.',
+	    items => {
+		type => 'string',
+		format => $map_fmt,
+	    },
+	},
+    },
+};
+
+sub private {
+    return $defaultData;
+}
+
+sub options {
+    return {
+	description => { optional => 1 },
+	map => {},
+    };
+}
+
+sub config {
+    return cfs_read_file($FILENAME);
+}
+
+sub lock_hwrng_config {
+    my ($code, $errmsg) = @_;
+
+    cfs_lock_file($FILENAME, undef, $code);
+    if (my $err = $@) {
+	$errmsg ? die "$errmsg: $err" : die $err;
+    }
+}
+
+sub write_hwrng_config {
+    my ($cfg) = @_;
+
+    cfs_write_file($FILENAME, $cfg);
+}
+
+sub find_on_current_node {
+    my ($id) = @_;
+
+    my $cfg = config();
+    my $node = PVE::INotify::nodename();
+
+    return get_node_mapping($cfg, $id, $node);
+}
+
+sub get_node_mapping {
+    my ($cfg, $id, $nodename) = @_;
+
+    return undef if !defined($cfg->{ids}->{$id});
+
+    my $res = [];
+    for my $map ($cfg->{ids}->{$id}->{map}->@*) {
+	my $entry = eval { parse_property_string($map_fmt, $map) };
+	warn $@ if $@;
+	if ($entry && $entry->{node} eq $nodename) {
+	    push $res->@*, $entry;
+	}
+    }
+
+    return $res;
+}
+
+PVE::Mapping::HWRNG->register();
+PVE::Mapping::HWRNG->init();
+
+1;
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [pve-devel] [PATCH cluster v2 2/9] cfs: add 'mapping/hwrng.cfg' to observed files
  2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
  2025-01-29 15:53 ` [pve-devel] [PATCH guest-common v2 1/9] mapping: add a hardware RNG mapping config Filip Schauer
@ 2025-01-29 15:53 ` Filip Schauer
  2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 3/9] introduce hardware rng mapping api Filip Schauer
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Filip Schauer @ 2025-01-29 15:53 UTC (permalink / raw)
  To: pve-devel

Observe the configuration file for hardware RNG mappings.

Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
 src/PVE/Cluster.pm  | 1 +
 src/pmxcfs/status.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/src/PVE/Cluster.pm b/src/PVE/Cluster.pm
index e0e3ee9..684b481 100644
--- a/src/PVE/Cluster.pm
+++ b/src/PVE/Cluster.pm
@@ -84,6 +84,7 @@ my $observed = {
     'sdn/.running-config' => 1,
     'virtual-guest/cpu-models.conf' => 1,
     'virtual-guest/profiles.cfg' => 1,
+    'mapping/hwrng.cfg' => 1,
     'mapping/pci.cfg' => 1,
     'mapping/usb.cfg' => 1,
 };
diff --git a/src/pmxcfs/status.c b/src/pmxcfs/status.c
index ff5fcc4..7001dfa 100644
--- a/src/pmxcfs/status.c
+++ b/src/pmxcfs/status.c
@@ -114,6 +114,7 @@ static memdb_change_t memdb_change_array[] = {
 	{ .path = "virtual-guest/cpu-models.conf" },
 	{ .path = "virtual-guest/profiles.cfg" },
 	{ .path = "firewall/cluster.fw" },
+	{ .path = "mapping/hwrng.cfg" },
 	{ .path = "mapping/pci.cfg" },
 	{ .path = "mapping/usb.cfg" },
 };
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [pve-devel] [PATCH manager v2 3/9] introduce hardware rng mapping api
  2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
  2025-01-29 15:53 ` [pve-devel] [PATCH guest-common v2 1/9] mapping: add a hardware RNG mapping config Filip Schauer
  2025-01-29 15:53 ` [pve-devel] [PATCH cluster v2 2/9] cfs: add 'mapping/hwrng.cfg' to observed files Filip Schauer
@ 2025-01-29 15:53 ` Filip Schauer
  2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 4/9] introduce hardware rng scanning api Filip Schauer
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Filip Schauer @ 2025-01-29 15:53 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
 PVE/API2/Cluster/Mapping.pm       |   7 +
 PVE/API2/Cluster/Mapping/HWRNG.pm | 286 ++++++++++++++++++++++++++++++
 PVE/API2/Cluster/Mapping/Makefile |   5 +-
 3 files changed, 296 insertions(+), 2 deletions(-)
 create mode 100644 PVE/API2/Cluster/Mapping/HWRNG.pm

diff --git a/PVE/API2/Cluster/Mapping.pm b/PVE/API2/Cluster/Mapping.pm
index 40386579..d245cc01 100644
--- a/PVE/API2/Cluster/Mapping.pm
+++ b/PVE/API2/Cluster/Mapping.pm
@@ -3,11 +3,17 @@ package PVE::API2::Cluster::Mapping;
 use strict;
 use warnings;
 
+use PVE::API2::Cluster::Mapping::HWRNG;
 use PVE::API2::Cluster::Mapping::PCI;
 use PVE::API2::Cluster::Mapping::USB;
 
 use base qw(PVE::RESTHandler);
 
+__PACKAGE__->register_method ({
+    subclass => "PVE::API2::Cluster::Mapping::HWRNG",
+    path => 'hwrng',
+});
+
 __PACKAGE__->register_method ({
     subclass => "PVE::API2::Cluster::Mapping::PCI",
     path => 'pci',
@@ -41,6 +47,7 @@ __PACKAGE__->register_method ({
 	my ($param) = @_;
 
 	my $result = [
+	    { name => 'hwrng' },
 	    { name => 'pci' },
 	    { name => 'usb' },
 	];
diff --git a/PVE/API2/Cluster/Mapping/HWRNG.pm b/PVE/API2/Cluster/Mapping/HWRNG.pm
new file mode 100644
index 00000000..553c3ec6
--- /dev/null
+++ b/PVE/API2/Cluster/Mapping/HWRNG.pm
@@ -0,0 +1,286 @@
+package PVE::API2::Cluster::Mapping::HWRNG;
+
+use strict;
+use warnings;
+
+use Storable qw(dclone);
+
+use PVE::Mapping::HWRNG ();
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::Tools qw(extract_param);
+
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method ({
+    name => 'index',
+    path => '',
+    method => 'GET',
+    # only proxy if we give the 'check-node' parameter
+    proxyto_callback => sub {
+	my ($rpcenv, $proxyto, $param) = @_;
+	return $param->{'check-node'} // 'localhost';
+    },
+    description => "List Hardware RNG Mappings",
+    permissions => {
+	description => "Only lists entries where you have 'Mapping.Modify', 'Mapping.Use' or".
+	    " 'Mapping.Audit' permissions on '/mapping/hwrng/<id>'.",
+	user => 'all',
+    },
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    'check-node' => get_standard_option('pve-node', {
+		description => "If given, checks the configurations on the given node for ".
+		    "correctness, and adds relevant errors to the devices.",
+		optional => 1,
+	    }),
+	},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => {
+		id => {
+		    type => 'string',
+		    description => "The logical ID of the mapping."
+		},
+		map => {
+		    type => 'array',
+		    description => "The entries of the mapping.",
+		    items => {
+			type => 'string',
+			description => "A mapping for a node.",
+		    },
+		},
+		description => {
+		    type => 'string',
+		    description => "A description of the logical mapping.",
+		},
+		error => {
+		    description => "A list of errors when 'check_node' is given.",
+		    items => {
+			type => 'object',
+			properties => {
+			    severity => {
+				type => "string",
+				description => "The severity of the error",
+			    },
+			    message => {
+				type => "string",
+				description => "The message of the error",
+			    },
+			},
+		    }
+		},
+	    },
+	},
+	links => [ { rel => 'child', href => "{id}" } ],
+    },
+    code => sub {
+	my ($param) = @_;
+
+	my $rpcenv = PVE::RPCEnvironment::get();
+	my $authuser = $rpcenv->get_user();
+	my $node = $param->{'check-node'};
+
+	die "Wrong node to check\n"
+	    if defined($node) && $node ne 'localhost' && $node ne PVE::INotify::nodename();
+
+	my $cfg = PVE::Mapping::HWRNG::config();
+
+	my $res = [];
+
+	my $privs = ['Mapping.Modify', 'Mapping.Use', 'Mapping.Audit'];
+
+	for my $id (keys $cfg->{ids}->%*) {
+	    next if !$rpcenv->check_full($authuser, "/mapping/hwrng/$id", $privs, 1, 1);
+	    next if !$cfg->{ids}->{$id};
+
+	    my $entry = dclone($cfg->{ids}->{$id});
+	    $entry->{id} = $id;
+	    $entry->{digest} = $cfg->{digest};
+
+	    if (defined($node)) {
+		$entry->{errors} = [];
+		if (my $mappings = PVE::Mapping::HWRNG::get_node_mapping($cfg, $id, $node)) {
+		    if (!scalar($mappings->@*)) {
+			push $entry->{errors}->@*, {
+			    severity => 'warning',
+			    message => "No mapping for node $node.",
+			};
+		    }
+		}
+	    }
+
+	    push @$res, $entry;
+	}
+
+	return $res;
+    },
+});
+
+__PACKAGE__->register_method ({
+    name => 'get',
+    protected => 1,
+    path => '{id}',
+    method => 'GET',
+    description => "Get Hardware RNG Mapping.",
+    permissions => {
+	check =>['or',
+	    ['perm', '/mapping/hwrng/{id}', ['Mapping.Audit']],
+	    ['perm', '/mapping/hwrng/{id}', ['Mapping.Use']],
+	    ['perm', '/mapping/hwrng/{id}', ['Mapping.Modify']],
+	],
+    },
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    id => {
+		type => 'string',
+		format => 'pve-configid',
+	    },
+	}
+    },
+    returns => { type => 'object' },
+    code => sub {
+	my ($param) = @_;
+
+	my $cfg = PVE::Mapping::HWRNG::config();
+	my $id = $param->{id};
+
+	my $entry = $cfg->{ids}->{$id};
+	die "mapping '$param->{id}' not found\n" if !defined($entry);
+
+	my $data = dclone($entry);
+
+	$data->{digest} = $cfg->{digest};
+
+	return $data;
+    },
+});
+
+__PACKAGE__->register_method ({
+    name => 'create',
+    protected => 1,
+    path => '',
+    method => 'POST',
+    description => "Create a new hardware RNG mapping.",
+    permissions => {
+	check => ['perm', '/mapping/hwrng', ['Mapping.Modify']],
+    },
+    parameters => PVE::Mapping::HWRNG->createSchema(1),
+    returns => {
+	type => 'null',
+    },
+    code => sub {
+	my ($param) = @_;
+
+	my $id = extract_param($param, 'id');
+
+	my $plugin = PVE::Mapping::HWRNG->lookup('hwrng');
+	my $opts = $plugin->check_config($id, $param, 1, 1);
+
+	PVE::Mapping::HWRNG::lock_hwrng_config(sub {
+	    my $cfg = PVE::Mapping::HWRNG::config();
+
+	    die "hwrng ID '$id' already defined\n" if defined($cfg->{ids}->{$id});
+
+	    $cfg->{ids}->{$id} = $opts;
+
+	    PVE::Mapping::HWRNG::write_hwrng_config($cfg);
+
+	}, "create hardware RNG mapping failed");
+
+	return;
+    },
+});
+
+__PACKAGE__->register_method ({
+    name => 'update',
+    protected => 1,
+    path => '{id}',
+    method => 'PUT',
+    description => "Update a Hardware RNG mapping.",
+    permissions => {
+	check => ['perm', '/mapping/hwrng/{id}', ['Mapping.Modify']],
+    },
+    parameters => PVE::Mapping::HWRNG->updateSchema(),
+    returns => {
+	type => 'null',
+    },
+    code => sub {
+	my ($param) = @_;
+
+	my $digest = extract_param($param, 'digest');
+	my $delete = extract_param($param, 'delete');
+	my $id = extract_param($param, 'id');
+
+	if ($delete) {
+	    $delete = [ PVE::Tools::split_list($delete) ];
+	}
+
+	PVE::Mapping::HWRNG::lock_hwrng_config(sub {
+	    my $cfg = PVE::Mapping::HWRNG::config();
+
+	    PVE::Tools::assert_if_modified($cfg->{digest}, $digest) if defined($digest);
+
+	    die "hwrng ID '$id' does not exist\n" if !defined($cfg->{ids}->{$id});
+
+	    my $plugin = PVE::Mapping::HWRNG->lookup('hwrng');
+	    my $opts = $plugin->check_config($id, $param, 1, 1);
+
+	    my $data = $cfg->{ids}->{$id};
+
+	    my $options = $plugin->private()->{options}->{hwrng};
+	    PVE::SectionConfig::delete_from_config($data, $options, $opts, $delete);
+
+	    $data->{$_} = $opts->{$_} for keys $opts->%*;
+
+	    PVE::Mapping::HWRNG::write_hwrng_config($cfg);
+	}, "update hardware RNG mapping failed");
+
+	return;
+    },
+});
+
+__PACKAGE__->register_method ({
+    name => 'delete',
+    protected => 1,
+    path => '{id}',
+    method => 'DELETE',
+    description => "Remove Hardware RNG Mapping.",
+    permissions => {
+	check => [ 'perm', '/mapping/hwrng', ['Mapping.Modify']],
+    },
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    id => {
+		type => 'string',
+		format => 'pve-configid',
+	    },
+	}
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+
+	my $id = $param->{id};
+
+	PVE::Mapping::HWRNG::lock_hwrng_config(sub {
+	    my $cfg = PVE::Mapping::HWRNG::config();
+
+	    if ($cfg->{ids}->{$id}) {
+		delete $cfg->{ids}->{$id};
+	    }
+
+	    PVE::Mapping::HWRNG::write_hwrng_config($cfg);
+
+	}, "delete hardware RNG mapping failed");
+
+	return;
+    }
+});
+
+1;
diff --git a/PVE/API2/Cluster/Mapping/Makefile b/PVE/API2/Cluster/Mapping/Makefile
index e7345ab4..f53f97af 100644
--- a/PVE/API2/Cluster/Mapping/Makefile
+++ b/PVE/API2/Cluster/Mapping/Makefile
@@ -2,8 +2,9 @@ include ../../../../defines.mk
 
 # for node independent, cluster-wide applicable, API endpoints
 # ensure we do not conflict with files shipped by pve-cluster!!
-PERLSOURCE= 	\
-	PCI.pm	\
+PERLSOURCE= 		\
+	HWRNG.pm	\
+	PCI.pm		\
 	USB.pm
 
 all:
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [pve-devel] [PATCH manager v2 4/9] introduce hardware rng scanning api
  2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
                   ` (2 preceding siblings ...)
  2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 3/9] introduce hardware rng mapping api Filip Schauer
@ 2025-01-29 15:53 ` Filip Schauer
  2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 5/9] ui: add hardware RNG resource mapping Filip Schauer
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Filip Schauer @ 2025-01-29 15:53 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
 PVE/API2/Hardware.pm       |  7 ++++++
 PVE/API2/Hardware/HWRNG.pm | 47 ++++++++++++++++++++++++++++++++++++++
 PVE/API2/Hardware/Makefile |  1 +
 3 files changed, 55 insertions(+)
 create mode 100644 PVE/API2/Hardware/HWRNG.pm

diff --git a/PVE/API2/Hardware.pm b/PVE/API2/Hardware.pm
index 1c6fd8f5..02503b22 100644
--- a/PVE/API2/Hardware.pm
+++ b/PVE/API2/Hardware.pm
@@ -6,11 +6,17 @@ use warnings;
 use PVE::JSONSchema qw(get_standard_option);
 use PVE::RESTHandler;
 
+use PVE::API2::Hardware::HWRNG;
 use PVE::API2::Hardware::PCI;
 use PVE::API2::Hardware::USB;
 
 use base qw(PVE::RESTHandler);
 
+__PACKAGE__->register_method ({
+    subclass => "PVE::API2::Hardware::HWRNG",
+    path => 'hwrng',
+});
+
 __PACKAGE__->register_method ({
     subclass => "PVE::API2::Hardware::PCI",
     path => 'pci',
@@ -47,6 +53,7 @@ __PACKAGE__->register_method ({
 	my ($param) = @_;
 
 	my $res = [
+	    { type => 'hwrng' },
 	    { type => 'pci' },
 	    { type => 'usb' },
 	];
diff --git a/PVE/API2/Hardware/HWRNG.pm b/PVE/API2/Hardware/HWRNG.pm
new file mode 100644
index 00000000..1c3ac240
--- /dev/null
+++ b/PVE/API2/Hardware/HWRNG.pm
@@ -0,0 +1,47 @@
+package PVE::API2::Hardware::HWRNG;
+
+use strict;
+use warnings;
+
+use PVE::JSONSchema qw(get_standard_option);
+
+use PVE::QemuServer::RNG qw(check_rng_source);
+
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method({
+    name => 'hwrngscan',
+    path => '',
+    method => 'GET',
+    description => "List local Hardware RNG devices.",
+    protected => 1,
+    proxyto => "node",
+    permissions => {
+	check => ['perm', '/', ['Sys.Audit']],
+    },
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    node => get_standard_option('pve-node'),
+	},
+    },
+    returns => {
+	type => 'array',
+	items => {
+	    type => "object",
+	    properties => {
+		path => { type => 'string'},
+	    },
+	},
+    },
+    code => sub {
+	my ($param) = @_;
+
+	eval { PVE::QemuServer::RNG::check_rng_source('/dev/hwrng') };
+	if (my $err = $@) {
+	    return [];
+	}
+
+	return [ { path => '/dev/hwrng' } ];
+    }
+});
diff --git a/PVE/API2/Hardware/Makefile b/PVE/API2/Hardware/Makefile
index 026a8dd6..1e552864 100644
--- a/PVE/API2/Hardware/Makefile
+++ b/PVE/API2/Hardware/Makefile
@@ -1,6 +1,7 @@
 include ../../../defines.mk
 
 PERLSOURCE=			\
+	HWRNG.pm		\
 	PCI.pm			\
 	USB.pm			\
 
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [pve-devel] [PATCH manager v2 5/9] ui: add hardware RNG resource mapping
  2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
                   ` (3 preceding siblings ...)
  2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 4/9] introduce hardware rng scanning api Filip Schauer
@ 2025-01-29 15:53 ` Filip Schauer
  2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 6/9] ui: allow use of mapped hardware RNGs as entropy sources for VMs Filip Schauer
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Filip Schauer @ 2025-01-29 15:53 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
 www/manager6/Makefile               |   2 +
 www/manager6/data/PermPathStore.js  |   1 +
 www/manager6/dc/Config.js           |  10 ++
 www/manager6/dc/HWRNGMapView.js     |  76 ++++++++++++++
 www/manager6/window/HWRNGMapEdit.js | 149 ++++++++++++++++++++++++++++
 5 files changed, 238 insertions(+)
 create mode 100644 www/manager6/dc/HWRNGMapView.js
 create mode 100644 www/manager6/window/HWRNGMapEdit.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index c94a5cdf..01a95c7e 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -138,6 +138,7 @@ JSSRC= 							\
 	window/TreeSettingsEdit.js			\
 	window/PCIMapEdit.js				\
 	window/USBMapEdit.js				\
+	window/HWRNGMapEdit.js				\
 	window/GuestImport.js				\
 	ha/Fencing.js					\
 	ha/GroupEdit.js					\
@@ -188,6 +189,7 @@ JSSRC= 							\
 	dc/RealmSyncJob.js				\
 	dc/PCIMapView.js				\
 	dc/USBMapView.js				\
+	dc/HWRNGMapView.js				\
 	lxc/CmdMenu.js					\
 	lxc/Config.js					\
 	lxc/CreateWizard.js				\
diff --git a/www/manager6/data/PermPathStore.js b/www/manager6/data/PermPathStore.js
index 8785a1d7..8212b17d 100644
--- a/www/manager6/data/PermPathStore.js
+++ b/www/manager6/data/PermPathStore.js
@@ -10,6 +10,7 @@ Ext.define('PVE.data.PermPathStore', {
 	{ 'value': '/access/realm' },
 	{ 'value': '/mapping' },
 	{ 'value': '/mapping/notifications' },
+	{ 'value': '/mapping/hwrng' },
 	{ 'value': '/mapping/pci' },
 	{ 'value': '/mapping/usb' },
 	{ 'value': '/nodes' },
diff --git a/www/manager6/dc/Config.js b/www/manager6/dc/Config.js
index 74728c83..3650f290 100644
--- a/www/manager6/dc/Config.js
+++ b/www/manager6/dc/Config.js
@@ -329,6 +329,16 @@ Ext.define('PVE.dc.Config', {
 			    title: gettext('USB Devices'),
 			    flex: 1,
 			},
+			{
+			    xtype: 'splitter',
+			    collapsible: false,
+			    performCollapse: false,
+			},
+			{
+			    xtype: 'pveDcHWRNGMapView',
+			    title: gettext('Hardware RNG Devices'),
+			    flex: 1,
+			},
 		    ],
 		},
 	    );
diff --git a/www/manager6/dc/HWRNGMapView.js b/www/manager6/dc/HWRNGMapView.js
new file mode 100644
index 00000000..27c0d2fc
--- /dev/null
+++ b/www/manager6/dc/HWRNGMapView.js
@@ -0,0 +1,76 @@
+Ext.define('pve-resource-hwrng-tree', {
+    extend: 'Ext.data.Model',
+    idProperty: 'internalId',
+    fields: ['type', 'text', 'path', 'description', 'digest'],
+});
+
+Ext.define('PVE.dc.HWRNGMapView', {
+    extend: 'PVE.tree.ResourceMapTree',
+    alias: 'widget.pveDcHWRNGMapView',
+
+    editWindowClass: 'PVE.window.HWRNGMapEditWindow',
+    baseUrl: '/cluster/mapping/hwrng',
+    mapIconCls: 'pve-itype-icon-die',
+    getStatusCheckUrl: (node) => `/nodes/${node}/hardware/hwrng`,
+    entryIdProperty: 'path',
+
+    checkValidity: function(data, node) {
+	let me = this;
+	let paths = {};
+	data.forEach((entry) => {
+	    paths[entry.path] = entry;
+	});
+	me.getRootNode()?.cascade(function(rec) {
+	    if (rec.data.node !== node || rec.data.type !== 'map') {
+		return;
+	    }
+
+	    let device;
+	    if (rec.data.path) {
+		device = paths[rec.data.path];
+	    }
+
+	    if (!device) {
+		rec.set('valid', false);
+		rec.set(
+		    'errmsg',
+		    Ext.String.format(gettext("Cannot find Hardware RNG device {0}"), rec.data.id),
+		);
+		rec.commit();
+		return;
+	    }
+
+	    rec.set('valid', true);
+	    rec.commit();
+	});
+    },
+
+    store: {
+	sorters: 'text',
+	model: 'pve-resource-hwrng-tree',
+	data: {},
+    },
+
+    columns: [
+	{
+	    xtype: 'treecolumn',
+	    text: gettext('ID/Node/Path'),
+	    dataIndex: 'text',
+	    width: 200,
+	},
+	{
+	    header: gettext('Status'),
+	    dataIndex: 'valid',
+	    flex: 1,
+	    renderer: 'renderStatus',
+	},
+	{
+	    header: gettext('Comment'),
+	    dataIndex: 'description',
+	    renderer: function(value, _meta, record) {
+		return Ext.String.htmlEncode(value ?? record.data.comment);
+	    },
+	    flex: 1,
+	},
+    ],
+});
diff --git a/www/manager6/window/HWRNGMapEdit.js b/www/manager6/window/HWRNGMapEdit.js
new file mode 100644
index 00000000..15e9008a
--- /dev/null
+++ b/www/manager6/window/HWRNGMapEdit.js
@@ -0,0 +1,149 @@
+Ext.define('PVE.window.HWRNGMapEditWindow', {
+    extend: 'Proxmox.window.Edit',
+    mixins: ['Proxmox.Mixin.CBind'],
+
+    width: 800,
+
+    subject: gettext('Hardware RNG mapping'),
+
+    onlineHelp: 'resource_mapping',
+
+    method: 'POST',
+
+    cbindData: function(initialConfig) {
+	let me = this;
+	me.isCreate = !me.name;
+	me.method = me.isCreate ? 'POST' : 'PUT';
+	me.hideMapping = !!me.entryOnly;
+	me.hideComment = me.name && !me.entryOnly;
+	me.hideNodeSelector = me.nodename || me.entryOnly;
+	me.hideNode = !me.nodename || !me.hideNodeSelector;
+	return {
+	    name: me.name,
+	    nodename: me.nodename,
+	};
+    },
+
+    submitUrl: function(_url, data) {
+	let me = this;
+	let name = me.isCreate ? '' : me.name;
+	return `/cluster/mapping/hwrng/${name}`;
+    },
+
+    controller: {
+	xclass: 'Ext.app.ViewController',
+
+	onGetValues: function(values) {
+	    let me = this;
+	    let view = me.getView();
+	    values.node ??= view.nodename;
+
+	    let name = values.name;
+	    let description = values.description;
+	    delete values.description;
+	    delete values.name;
+	    values.path = '/dev/hwrng';
+
+	    let map = [];
+	    if (me.originalMap) {
+		map = PVE.Parser.filterPropertyStringList(me.originalMap, (e) => e.node !== values.node);
+	    }
+	    if (values.id) {
+		map.push(PVE.Parser.printPropertyString(values));
+	    }
+
+	    values = { map };
+	    if (description) {
+		values.description = description;
+	    }
+
+	    if (view.isCreate) {
+		values.id = name;
+	    }
+
+	    return values;
+	},
+
+	onSetValues: function(values) {
+	    let me = this;
+	    let view = me.getView();
+	    me.originalMap = [...values.map];
+	    let configuredNodes = [];
+	    PVE.Parser.filterPropertyStringList(values.map, (e) => {
+		configuredNodes.push(e.node);
+		if (e.node === view.nodename) {
+		    values = e;
+		}
+		return false;
+	    });
+
+	    me.lookup('nodeselector').disallowedNodes = configuredNodes;
+
+	    return values;
+	},
+    },
+
+    items: [
+	{
+	    xtype: 'inputpanel',
+	    onGetValues: function(values) {
+		return this.up('window').getController().onGetValues(values);
+	    },
+
+	    onSetValues: function(values) {
+		return this.up('window').getController().onSetValues(values);
+	    },
+
+	    column1: [
+		{
+		    xtype: 'pmxDisplayEditField',
+		    fieldLabel: gettext('Name'),
+		    cbind: {
+			editable: '{!name}',
+			value: '{name}',
+			submitValue: '{isCreate}',
+		    },
+		    name: 'name',
+		    allowBlank: false,
+		},
+		{
+		    xtype: 'displayfield',
+		    fieldLabel: gettext('Mapping on Node'),
+		    labelWidth: 120,
+		    name: 'node',
+		    cbind: {
+			value: '{nodename}',
+			disabled: '{hideNode}',
+			hidden: '{hideNode}',
+		    },
+		    allowBlank: false,
+		},
+		{
+		    xtype: 'pveNodeSelector',
+		    reference: 'nodeselector',
+		    fieldLabel: gettext('Mapping on Node'),
+		    labelWidth: 120,
+		    name: 'node',
+		    cbind: {
+			disabled: '{hideNodeSelector}',
+			hidden: '{hideNodeSelector}',
+		    },
+		    allowBlank: false,
+		},
+	    ],
+
+	    columnB: [
+		{
+		    xtype: 'proxmoxtextfield',
+		    fieldLabel: gettext('Comment'),
+		    submitValue: true,
+		    name: 'description',
+		    cbind: {
+			disabled: '{hideComment}',
+			hidden: '{hideComment}',
+		    },
+		},
+	    ],
+	},
+    ],
+});
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [pve-devel] [PATCH manager v2 6/9] ui: allow use of mapped hardware RNGs as entropy sources for VMs
  2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
                   ` (4 preceding siblings ...)
  2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 5/9] ui: add hardware RNG resource mapping Filip Schauer
@ 2025-01-29 15:53 ` Filip Schauer
  2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 7/9] refactor: move rng related code into its own module Filip Schauer
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 15+ messages in thread
From: Filip Schauer @ 2025-01-29 15:53 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
 www/manager6/Makefile                 |  1 +
 www/manager6/form/HWRNGMapSelector.js | 99 +++++++++++++++++++++++++++
 www/manager6/qemu/HardwareView.js     |  9 ++-
 www/manager6/qemu/RNGEdit.js          | 79 ++++++++++++++-------
 4 files changed, 159 insertions(+), 29 deletions(-)
 create mode 100644 www/manager6/form/HWRNGMapSelector.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 01a95c7e..d148a1c9 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -44,6 +44,7 @@ JSSRC= 							\
 	form/GuestIDSelector.js				\
 	form/HashAlgorithmSelector.js			\
 	form/HotplugFeatureSelector.js			\
+	form/HWRNGMapSelector.js			\
 	form/IPProtocolSelector.js			\
 	form/IPRefSelector.js				\
 	form/MDevSelector.js				\
diff --git a/www/manager6/form/HWRNGMapSelector.js b/www/manager6/form/HWRNGMapSelector.js
new file mode 100644
index 00000000..1c795d2d
--- /dev/null
+++ b/www/manager6/form/HWRNGMapSelector.js
@@ -0,0 +1,99 @@
+Ext.define('PVE.form.HWRNGMapSelector', {
+    extend: 'Proxmox.form.ComboGrid',
+    alias: 'widget.pveHWRNGMapSelector',
+
+    store: {
+	fields: ['name', 'path'],
+	filterOnLoad: true,
+	sorters: [
+	    {
+		property: 'name',
+		direction: 'ASC',
+	    },
+	],
+    },
+
+    allowBlank: false,
+    autoSelect: false,
+    displayField: 'id',
+    valueField: 'id',
+
+    listConfig: {
+	width: 800,
+	columns: [
+	    {
+		header: gettext('Name'),
+		dataIndex: 'id',
+		flex: 1,
+	    },
+	    {
+		header: gettext('Status'),
+		dataIndex: 'errors',
+		flex: 2,
+		renderer: function(value) {
+		    let me = this;
+
+		    if (!Ext.isArray(value) || !value?.length) {
+			return `<i class="fa fa-check-circle good"></i> ${gettext('Mapping matches host data')}`;
+		    }
+
+		    let errors = [];
+
+		    value.forEach((error) => {
+			let iconCls;
+			switch (error?.severity) {
+			    case 'warning':
+				iconCls = 'fa-exclamation-circle warning';
+				break;
+			    case 'error':
+				iconCls = 'fa-times-circle critical';
+				break;
+			}
+
+			let message = error?.message;
+			let icon = `<i class="fa ${iconCls}"></i>`;
+			if (iconCls !== undefined) {
+			    errors.push(`${icon} ${message}`);
+			}
+		    });
+
+		    return errors.join('<br>');
+		},
+	    },
+	    {
+		header: gettext('Comment'),
+		dataIndex: 'description',
+		flex: 1,
+		renderer: Ext.String.htmlEncode,
+	    },
+	],
+    },
+
+    setNodename: function(nodename) {
+	var me = this;
+
+	if (!nodename || me.nodename === nodename) {
+	    return;
+	}
+
+	me.nodename = nodename;
+
+	me.store.setProxy({
+	    type: 'proxmox',
+	    url: `/api2/json/cluster/mapping/hwrng?check-node=${nodename}`,
+	});
+
+	me.store.load();
+    },
+
+    initComponent: function() {
+	var me = this;
+
+	var nodename = me.nodename;
+	me.nodename = undefined;
+
+        me.callParent();
+
+	me.setNodename(nodename);
+    },
+});
diff --git a/www/manager6/qemu/HardwareView.js b/www/manager6/qemu/HardwareView.js
index c6d193fc..8085e288 100644
--- a/www/manager6/qemu/HardwareView.js
+++ b/www/manager6/qemu/HardwareView.js
@@ -315,8 +315,8 @@ Ext.define('PVE.qemu.HardwareView', {
 	rows.rng0 = {
 	    group: 45,
 	    tdCls: 'pve-itype-icon-die',
-	    editor: caps.nodes['Sys.Console'] ? 'PVE.qemu.RNGEdit' : undefined,
-	    never_delete: !caps.nodes['Sys.Console'],
+	    editor: caps.vms['VM.Config.HWType'] || caps.mapping['Mapping.Use'] ? 'PVE.qemu.RNGEdit' : undefined,
+	    never_delete: !caps.vms['VM.Config.HWType'] && !caps.mapping['Mapping.Use'],
 	    header: gettext("VirtIO RNG"),
 	};
 
@@ -588,7 +588,6 @@ Ext.define('PVE.qemu.HardwareView', {
 	    });
 
 	    // heuristic only for disabling some stuff, the backend has the final word.
-	    const noSysConsolePerm = !caps.nodes['Sys.Console'];
 	    const noHWPerm = !caps.nodes['Sys.Console'] && !caps.mapping['Mapping.Use'];
 	    const noVMConfigHWTypePerm = !caps.vms['VM.Config.HWType'];
 	    const noVMConfigNetPerm = !caps.vms['VM.Config.Network'];
@@ -601,7 +600,7 @@ Ext.define('PVE.qemu.HardwareView', {
 	    me.down('#addAudio').setDisabled(noVMConfigHWTypePerm || isAtLimit('audio'));
 	    me.down('#addSerial').setDisabled(noVMConfigHWTypePerm || isAtLimit('serial'));
 	    me.down('#addNet').setDisabled(noVMConfigNetPerm || isAtLimit('net'));
-	    me.down('#addRng').setDisabled(noSysConsolePerm || isAtLimit('rng'));
+	    me.down('#addRng').setDisabled(noVMConfigHWTypePerm || isAtLimit('rng'));
 	    efidisk_menuitem.setDisabled(noVMConfigDiskPerm || isAtLimit('efidisk'));
 	    me.down('#addTpmState').setDisabled(noVMConfigDiskPerm || isAtLimit('tpmstate'));
 	    me.down('#addCloudinitDrive').setDisabled(noVMConfigCDROMPerm || noVMConfigCloudinitPerm || hasCloudInit);
@@ -745,7 +744,7 @@ Ext.define('PVE.qemu.HardwareView', {
 				text: gettext("VirtIO RNG"),
 				itemId: 'addRng',
 				iconCls: 'pve-itype-icon-die',
-				disabled: !caps.nodes['Sys.Console'],
+				disabled: !caps.vms['VM.Config.HWType'] && !caps.mapping['Mapping.Use'],
 				handler: editorFactory('RNGEdit'),
 			    },
 			],
diff --git a/www/manager6/qemu/RNGEdit.js b/www/manager6/qemu/RNGEdit.js
index e34e2c08..fab8c1b0 100644
--- a/www/manager6/qemu/RNGEdit.js
+++ b/www/manager6/qemu/RNGEdit.js
@@ -1,9 +1,19 @@
 Ext.define('PVE.qemu.RNGInputPanel', {
     extend: 'Proxmox.panel.InputPanel',
     xtype: 'pveRNGInputPanel',
+    mixins: ['Proxmox.Mixin.CBind'],
 
     onlineHelp: 'qm_virtio_rng',
 
+    cbindData: function(initialConfig) {
+	let me = this;
+	if (!me.pveSelNode) {
+	    throw "no pveSelNode given";
+	}
+
+	return { nodename: me.pveSelNode.data.node };
+    },
+
     onGetValues: function(values) {
 	if (values.max_bytes === "") {
 	    values.max_bytes = "0";
@@ -23,6 +33,10 @@ Ext.define('PVE.qemu.RNGInputPanel', {
 	    values.max_bytes = null;
 	}
 
+	if (values.mapping) {
+	    values.source = 'mapped';
+	}
+
 	this.callParent(arguments);
     },
 
@@ -35,27 +49,49 @@ Ext.define('PVE.qemu.RNGInputPanel', {
 		    limitWarning.setHidden(!!newVal);
 		},
 	    },
-	    '#source': {
-		change: function(el, newVal) {
-		    let limitWarning = this.lookupReference('sourceWarning');
-		    limitWarning.setHidden(newVal !== '/dev/random');
-		},
-	    },
 	},
     },
 
     items: [{
-	itemId: 'source',
-	name: 'source',
-	xtype: 'proxmoxKVComboBox',
-	value: '/dev/urandom',
-	fieldLabel: gettext('Entropy source'),
-	labelWidth: 130,
-	comboItems: [
-	    ['/dev/urandom', '/dev/urandom'],
-	    ['/dev/random', '/dev/random'],
-	    ['/dev/hwrng', '/dev/hwrng'],
-	],
+	xtype: 'fieldcontainer',
+	defaultType: 'radiofield',
+	layout: 'fit',
+	items: [{
+	    name: 'source',
+	    inputValue: '/dev/urandom',
+	    boxLabel: '/dev/urandom',
+	    checked: true,
+	},
+	{
+	    name: 'source',
+	    inputValue: '/dev/random',
+	    boxLabel: '/dev/random',
+	},
+	{
+	    name: 'source',
+	    inputValue: 'mapped',
+	    boxLabel: gettext('Use mapped Hardware RNG device'),
+	    reference: 'mapped',
+	    submitValue: false,
+	    listeners: {
+		change: function(f, value) {
+		    let me = this;
+		    if (!me.rendered) {
+			return;
+		    }
+		    me.up().down('field[name=mapping]').setDisabled(!value);
+		},
+	    },
+	},
+	{
+	    xtype: 'pveHWRNGMapSelector',
+	    name: 'mapping',
+	    cbind: { nodename: '{nodename}' },
+	    allowBlank: false,
+	    fieldLabel: gettext('Choose Device'),
+	    labelAlign: 'right',
+	    disabled: true,
+	}],
     },
     {
 	xtype: 'numberfield',
@@ -77,13 +113,6 @@ Ext.define('PVE.qemu.RNGInputPanel', {
 	labelWidth: 130,
 	emptyText: '1000',
     },
-    {
-	xtype: 'displayfield',
-	reference: 'sourceWarning',
-	value: gettext('Using /dev/random as entropy source is discouraged, as it can lead to host entropy starvation. /dev/urandom is preferred, and does not lead to a decrease in security in practice.'),
-	userCls: 'pmx-hint',
-	hidden: true,
-    },
     {
 	xtype: 'displayfield',
 	reference: 'limitWarning',
@@ -95,11 +124,13 @@ Ext.define('PVE.qemu.RNGInputPanel', {
 
 Ext.define('PVE.qemu.RNGEdit', {
     extend: 'Proxmox.window.Edit',
+    mixins: ['Proxmox.Mixin.CBind'],
 
     subject: gettext('VirtIO RNG'),
 
     items: [{
 	xtype: 'pveRNGInputPanel',
+	cbind: { pveSelNode: '{pveSelNode}' },
     }],
 
     initComponent: function() {
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [pve-devel] [PATCH qemu-server v2 7/9] refactor: move rng related code into its own module
  2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
                   ` (5 preceding siblings ...)
  2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 6/9] ui: allow use of mapped hardware RNGs as entropy sources for VMs Filip Schauer
@ 2025-01-29 15:53 ` Filip Schauer
  2025-01-30 12:17   ` Fiona Ebner
  2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 8/9] allow non-root users to set /dev/u?random as an RNG source Filip Schauer
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 15+ messages in thread
From: Filip Schauer @ 2025-01-29 15:53 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
 PVE/QemuServer.pm       |  83 +++---------------------
 PVE/QemuServer/Makefile |   1 +
 PVE/QemuServer/RNG.pm   | 135 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 145 insertions(+), 74 deletions(-)
 create mode 100644 PVE/QemuServer/RNG.pm

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 5cde94a1..93e65825 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -61,6 +61,7 @@ use PVE::QemuServer::Memory qw(get_current_memory);
 use PVE::QemuServer::Monitor qw(mon_cmd);
 use PVE::QemuServer::PCI qw(print_pci_addr print_pcie_addr print_pcie_root_port parse_hostpci);
 use PVE::QemuServer::QMPHelpers qw(qemu_deviceadd qemu_devicedel qemu_objectadd qemu_objectdel);
+use PVE::QemuServer::RNG;
 use PVE::QemuServer::USB;
 
 my $have_sdn;
@@ -249,39 +250,6 @@ my $spice_enhancements_fmt = {
     },
 };
 
-my $rng_fmt = {
-    source => {
-	type => 'string',
-	enum => ['/dev/urandom', '/dev/random', '/dev/hwrng'],
-	default_key => 1,
-	description => "The file on the host to gather entropy from. In most cases '/dev/urandom'"
-	    ." should be preferred over '/dev/random' to avoid entropy-starvation issues on the"
-	    ." host. 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.",
-    },
-    max_bytes => {
-	type => 'integer',
-	description => "Maximum bytes of entropy allowed to get injected into the guest every"
-	    ." 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use"
-	    ." `0` to disable limiting (potentially dangerous!).",
-	optional => 1,
-
-	# default is 1 KiB/s, provides enough entropy to the guest to avoid boot-starvation issues
-	# (e.g. systemd etc...) while allowing no chance of overwhelming the host, provided we're
-	# reading from /dev/urandom
-	default => 1024,
-    },
-    period => {
-	type => 'integer',
-	description => "Every 'period' milliseconds the entropy-injection quota is reset, allowing"
-	    ." the guest to retrieve another 'max_bytes' of entropy.",
-	optional => 1,
-	default => 1000,
-    },
-};
-
 my $meta_info_fmt = {
     'ctime' => {
 	type => 'integer',
@@ -724,7 +692,7 @@ EODESCR
     },
     rng0 => {
 	type => 'string',
-	format => $rng_fmt,
+	format => $PVE::QemuServer::RNG::rng_fmt,
 	description => "Configure a VirtIO-based Random Number Generator.",
 	optional => 1,
     },
@@ -2078,16 +2046,6 @@ sub parse_vga {
     return $res;
 }
 
-sub parse_rng {
-    my ($value) = @_;
-
-    return if !$value;
-
-    my $res = eval { parse_property_string($rng_fmt, $value) };
-    warn $@ if $@;
-    return $res;
-}
-
 sub parse_meta_info {
     my ($value) = @_;
 
@@ -3940,20 +3898,14 @@ sub config_to_command {
 	}
     }
 
-    my $rng = $conf->{rng0} ? parse_rng($conf->{rng0}) : undef;
+    my $rng = $conf->{rng0} ? PVE::QemuServer::RNG::parse_rng($conf->{rng0}) : undef;
     if ($rng && $version_guard->(4, 1, 2)) {
-	check_rng_source($rng->{source});
-
-	my $max_bytes = $rng->{max_bytes} // $rng_fmt->{max_bytes}->{default};
-	my $period = $rng->{period} // $rng_fmt->{period}->{default};
-	my $limiter_str = "";
-	if ($max_bytes) {
-	    $limiter_str = ",max-bytes=$max_bytes,period=$period";
-	}
-
-	my $rng_addr = print_pci_addr("rng0", $bridges, $arch, $machine_type);
-	push @$devices, '-object', "rng-random,filename=$rng->{source},id=rng0";
-	push @$devices, '-device', "virtio-rng-pci,rng=rng0$limiter_str$rng_addr";
+	my $rng_object = PVE::QemuServer::RNG::print_rng_object('rng0', $rng);
+	my $rng_device = PVE::QemuServer::RNG::print_rng_device(
+	    'rng0', $rng, $bridges, $arch, $machine_type
+	);
+	push @$devices, '-object', $rng_object;
+	push @$devices, '-device', $rng_device;
     }
 
     my $spice_port;
@@ -4235,23 +4187,6 @@ sub config_to_command {
     return wantarray ? ($cmd, $vollist, $spice_port, $pci_devices) : $cmd;
 }
 
-sub check_rng_source {
-    my ($source) = @_;
-
-    # mostly relevant for /dev/hwrng, but doesn't hurt to check others too
-    die "cannot create VirtIO RNG device: source file '$source' doesn't exist\n"
-	if ! -e $source;
-
-    my $rng_current = '/sys/devices/virtual/misc/hw_random/rng_current';
-    if ($source eq '/dev/hwrng' && file_read_firstline($rng_current) eq 'none') {
-	# Needs to abort, otherwise QEMU crashes on first rng access. Note that rng_current cannot
-	# be changed to 'none' manually, so once the VM is past this point, it's no longer an issue.
-	die "Cannot start VM with passed-through RNG device: '/dev/hwrng' exists, but"
-	    ." '$rng_current' is set to 'none'. Ensure that a compatible hardware-RNG is attached"
-	    ." to the host.\n";
-    }
-}
-
 sub spice_port {
     my ($vmid) = @_;
 
diff --git a/PVE/QemuServer/Makefile b/PVE/QemuServer/Makefile
index 89d12091..72c287fc 100644
--- a/PVE/QemuServer/Makefile
+++ b/PVE/QemuServer/Makefile
@@ -1,4 +1,5 @@
 SOURCES=PCI.pm		\
+	RNG.pm		\
 	USB.pm		\
 	Memory.pm	\
 	ImportDisk.pm	\
diff --git a/PVE/QemuServer/RNG.pm b/PVE/QemuServer/RNG.pm
new file mode 100644
index 00000000..f7a62f3b
--- /dev/null
+++ b/PVE/QemuServer/RNG.pm
@@ -0,0 +1,135 @@
+package PVE::QemuServer::RNG;
+
+use strict;
+use warnings;
+
+use PVE::QemuServer::PCI qw(print_pci_addr);
+use PVE::JSONSchema;
+use PVE::Tools qw(file_read_firstline);
+use base 'Exporter';
+
+our @EXPORT_OK = qw(
+parse_rng
+check_rng_source
+print_rng_device
+print_rng_object
+);
+
+our $rng_fmt = {
+    source => {
+	type => 'string',
+	enum => ['/dev/urandom', '/dev/random', '/dev/hwrng'],
+	default_key => 1,
+	optional => 1,
+	description => "The file on the host to gather entropy from. In most cases '/dev/urandom'"
+	    ." should be preferred over '/dev/random' to avoid entropy-starvation issues on the"
+	    ." host. 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.",
+    },
+    max_bytes => {
+	type => 'integer',
+	description => "Maximum bytes of entropy allowed to get injected into the guest every"
+	    ." 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use"
+	    ." `0` to disable limiting (potentially dangerous!).",
+	optional => 1,
+
+	# default is 1 KiB/s, provides enough entropy to the guest to avoid boot-starvation issues
+	# (e.g. systemd etc...) while allowing no chance of overwhelming the host, provided we're
+	# reading from /dev/urandom
+	default => 1024,
+    },
+    period => {
+	type => 'integer',
+	description => "Every 'period' milliseconds the entropy-injection quota is reset, allowing"
+	    ." the guest to retrieve another 'max_bytes' of entropy.",
+	optional => 1,
+	default => 1000,
+    },
+};
+
+PVE::JSONSchema::register_format('pve-qm-rng', $rng_fmt);
+
+our $rngdesc = {
+    type => 'string',
+    format => $rng_fmt,
+    optional => 1,
+    description => "Configure a VirtIO-based Random Number Generator.",
+};
+PVE::JSONSchema::register_standard_option('pve-qm-rng', $rngdesc);
+
+sub parse_rng {
+    my ($value) = @_;
+
+    return if !$value;
+
+    my $res = eval { PVE::JSONSchema::parse_property_string($rng_fmt, $value) };
+    warn $@ if $@;
+
+    my $source = $res->{source};
+
+    return $res;
+}
+
+sub check_rng_source {
+    my ($source) = @_;
+
+    # mostly relevant for /dev/hwrng, but doesn't hurt to check others too
+    die "cannot create VirtIO RNG device: source file '$source' doesn't exist\n"
+	if ! -e $source;
+
+    my $rng_current = '/sys/devices/virtual/misc/hw_random/rng_current';
+    if ($source eq '/dev/hwrng' && file_read_firstline($rng_current) eq 'none') {
+	# Needs to abort, otherwise QEMU crashes on first rng access. Note that rng_current cannot
+	# be changed to 'none' manually, so once the VM is past this point, it's no longer an issue.
+	die "Cannot start VM with passed-through RNG device: '/dev/hwrng' exists, but"
+	    ." '$rng_current' is set to 'none'. Ensure that a compatible hardware-RNG is attached"
+	    ." to the host.\n";
+    }
+}
+
+sub get_rng_source_path {
+    my ($rng) = @_;
+
+    my $source = $rng->{source};
+
+    if (defined($source)) {
+	return $source;
+    }
+
+    return;
+}
+
+sub print_rng_device {
+    my ($id, $rng, $bridges, $arch, $machine) = @_;
+
+    return if !$rng;
+
+    my $source_path = get_rng_source_path($rng);
+    check_rng_source($source_path);
+
+    my $max_bytes = $rng->{max_bytes} // $rng_fmt->{max_bytes}->{default};
+    my $period = $rng->{period} // $rng_fmt->{period}->{default};
+    my $limiter_str = "";
+    if ($max_bytes) {
+	$limiter_str = ",max-bytes=$max_bytes,period=$period";
+    }
+
+    my $rng_addr = print_pci_addr($id, $bridges, $arch, $machine);
+
+    return "virtio-rng-pci,rng=$id$limiter_str$rng_addr";
+}
+
+sub print_rng_object {
+    my ($id, $rng) = @_;
+
+    return if !$rng;
+
+    my $source_path = get_rng_source_path($rng);
+    check_rng_source($source_path);
+
+    return "rng-random,filename=$source_path,id=$id";
+}
+
+1;
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [pve-devel] [PATCH qemu-server v2 8/9] allow non-root users to set /dev/u?random as an RNG source
  2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
                   ` (6 preceding siblings ...)
  2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 7/9] refactor: move rng related code into its own module Filip Schauer
@ 2025-01-29 15:53 ` Filip Schauer
  2025-01-30 12:18   ` Fiona Ebner
  2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 9/9] let VirtIO RNG devices source entropy from mapped HWRNGs Filip Schauer
  2025-01-30 12:17 ` [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Fiona Ebner
  9 siblings, 1 reply; 15+ messages in thread
From: Filip Schauer @ 2025-01-29 15:53 UTC (permalink / raw)
  To: pve-devel

Allow non-root users with the VM.Config.HWType privilege to configure
/dev/urandom & /dev/random as an entropy source for a VirtIO RNG device.
/dev/hwrng remains restricted to the root user.

Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
---
 PVE/API2/Qemu.pm  | 42 ++++++++++++++++++++++++++++++++++++++++++
 PVE/QemuServer.pm | 13 +++++++++++--
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index db356b7e..8262c9d4 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -670,6 +670,7 @@ my $hwtypeoptions = {
     'vga' => 1,
     'watchdog' => 1,
     'audio0' => 1,
+    'rng0' => 1,
 };
 
 my $generaloptions = {
@@ -798,6 +799,36 @@ my sub check_vm_create_hostpci_perm {
     return 1;
 };
 
+my sub check_rng_perm {
+    my ($rpcenv, $authuser, $vmid, $pool, $opt, $value) = @_;
+
+    return 1 if $authuser eq 'root@pam';
+
+    $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.HWType']);
+
+    my $device = PVE::JSONSchema::parse_property_string('pve-qm-rng', $value);
+    if ($device->{source}) {
+	if ($device->{source} eq '/dev/hwrng') {
+	    die "only root can set '$opt' config for a non-mapped Hardware RNG device\n";
+	}
+    }
+
+    return 1;
+}
+
+my sub check_vm_create_rng_perm {
+    my ($rpcenv, $authuser, $vmid, $pool, $param) = @_;
+
+    return 1 if $authuser eq 'root@pam';
+
+    foreach my $opt (keys %{$param}) {
+	next if $opt !~ m/^rng\d+$/;
+	check_rng_perm($rpcenv, $authuser, $vmid, $pool, $opt, $param->{$opt});
+    }
+
+    return 1;
+};
+
 my $check_vm_modify_config_perm = sub {
     my ($rpcenv, $authuser, $vmid, $pool, $key_list) = @_;
 
@@ -1111,6 +1142,7 @@ __PACKAGE__->register_method({
 	    &$check_vm_create_serial_perm($rpcenv, $authuser, $vmid, $pool, $param);
 	    check_vm_create_usb_perm($rpcenv, $authuser, $vmid, $pool, $param);
 	    check_vm_create_hostpci_perm($rpcenv, $authuser, $vmid, $pool, $param);
+	    check_vm_create_rng_perm($rpcenv, $authuser, $vmid, $pool, $param);
 
 	    PVE::QemuServer::check_bridge_access($rpcenv, $authuser, $param);
 	    &$check_cpu_model_access($rpcenv, $authuser, $param);
@@ -2008,6 +2040,10 @@ my $update_vm_api  = sub {
 		    check_hostpci_perm($rpcenv, $authuser, $vmid, undef, $opt, $val);
 		    PVE::QemuConfig->add_to_pending_delete($conf, $opt, $force);
 		    PVE::QemuConfig->write_config($vmid, $conf);
+		} elsif ($opt eq m/^rng\d+$/) {
+		    check_rng_perm($rpcenv, $authuser, $vmid, undef, $opt, $val);
+		    PVE::QemuConfig->add_to_pending_delete($conf, $opt, $force);
+		    PVE::QemuConfig->write_config($vmid, $conf);
 		} elsif ($opt eq 'tags') {
 		    assert_tag_permissions($vmid, $val, '', $rpcenv, $authuser);
 		    delete $conf->{$opt};
@@ -2098,6 +2134,12 @@ my $update_vm_api  = sub {
 		    }
 		    check_hostpci_perm($rpcenv, $authuser, $vmid, undef, $opt, $param->{$opt});
 		    $conf->{pending}->{$opt} = $param->{$opt};
+		} elsif ($opt =~ m/^rng\d+$/) {
+		    if (my $oldvalue = $conf->{$opt}) {
+			check_rng_perm($rpcenv, $authuser, $vmid, undef, $opt, $oldvalue);
+		    }
+		    check_rng_perm($rpcenv, $authuser, $vmid, undef, $opt, $param->{$opt});
+		    $conf->{pending}->{$opt} = $param->{$opt};
 		} elsif ($opt eq 'tags') {
 		    assert_tag_permissions($vmid, $conf->{$opt}, $param->{$opt}, $rpcenv, $authuser);
 		    $conf->{pending}->{$opt} = PVE::GuestHelpers::get_unique_tags($param->{$opt});
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 93e65825..606f51fa 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -6602,8 +6602,17 @@ sub check_mapping_access {
 	    } else {
 		die "either 'host' or 'mapping' must be set.\n";
 	    }
-       }
-   }
+	} elsif ($opt =~ m/^rng\d+$/) {
+	    my $device = PVE::JSONSchema::parse_property_string('pve-qm-rng', $conf->{$opt});
+
+	    if ($device->{source}) {
+		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';
+		}
+	    }
+	}
+    }
 };
 
 sub check_restore_permissions {
-- 
2.39.5



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [pve-devel] [PATCH qemu-server v2 9/9] let VirtIO RNG devices source entropy from mapped HWRNGs
  2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
                   ` (7 preceding siblings ...)
  2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 8/9] allow non-root users to set /dev/u?random as an RNG source Filip Schauer
@ 2025-01-29 15:53 ` Filip Schauer
  2025-01-30 12:17 ` [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Fiona Ebner
  9 siblings, 0 replies; 15+ messages in thread
From: Filip Schauer @ 2025-01-29 15:53 UTC (permalink / raw)
  To: pve-devel

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@proxmox.com>
---
 PVE/API2/Qemu.pm      |  5 +++++
 PVE/QemuServer.pm     |  5 +++++
 PVE/QemuServer/RNG.pm | 25 +++++++++++++++++++++++--
 3 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 8262c9d4..e8567ff3 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -808,9 +808,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 606f51fa..4a36e778 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -6606,10 +6606,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 f7a62f3b..ede5ffde 100644
--- a/PVE/QemuServer/RNG.pm
+++ b/PVE/QemuServer/RNG.pm
@@ -5,6 +5,7 @@ use warnings;
 
 use PVE::QemuServer::PCI qw(print_pci_addr);
 use PVE::JSONSchema;
+use PVE::Mapping::HWRNG;
 use PVE::Tools qw(file_read_firstline);
 use base 'Exporter';
 
@@ -25,8 +26,15 @@ our $rng_fmt = {
 	    ." should be preferred over '/dev/random' to avoid entropy-starvation issues on the"
 	    ." host. 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.",
+	    ." with real entropy on the guest as well.",
+    },
+    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',
@@ -68,6 +76,9 @@ sub parse_rng {
     warn $@ if $@;
 
     my $source = $res->{source};
+    my $mapping = $res->{mapping};
+
+    return if $source && $mapping; # not a valid configuration
 
     return $res;
 }
@@ -93,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


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user
  2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
                   ` (8 preceding siblings ...)
  2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 9/9] let VirtIO RNG devices source entropy from mapped HWRNGs Filip Schauer
@ 2025-01-30 12:17 ` Fiona Ebner
  2025-02-10 15:47   ` Filip Schauer
  9 siblings, 1 reply; 15+ messages in thread
From: Fiona Ebner @ 2025-01-30 12:17 UTC (permalink / raw)
  To: Proxmox VE development discussion, Filip Schauer

Am 29.01.25 um 16:53 schrieb Filip Schauer:
> Allow users with the VM.Config.HWType privilege to configure VirtIO RNG
> devices on VMs with either /dev/urandom or /dev/random as the entropy
> source.
> 
> Further introduce hardware RNG device mapping to be able to selectively
> allow non-root users with the Mapping.Use privilege to configure
> hardware RNG devices as entropy sources.
>

It's a lot of overhead for a very specific kind of device. What irks me
is that we have a lot of boilerplate duplication for each new mapping
type, also for the API endpoints. Nothing specific to your series of
course, but maybe something we could/should address? In the UI, it
probably would also be better to have a separate view for each mapping
type? Markus needs directory mappings for virtio-fs and then we would
have 4 different mapping kinds in a single view, which IMHO is just too
much.

Maybe we can introduce a dedicated base module for Mapping Section
configs? And also have standard options for the common params in the
schema. Same applies for the API endpoints, would be nice to have a way
to more easily generate them or at least capture the functionality that
is 1:1 with some helpers. Again, nothing specific to your series. Just
putting it out there for discussion or if somebody wants to grab that
task :)

When I try to add a mapping in the UI, I get
Parameter verification failed. (400)
map: type check ('array') failed


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [pve-devel] [PATCH qemu-server v2 7/9] refactor: move rng related code into its own module
  2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 7/9] refactor: move rng related code into its own module Filip Schauer
@ 2025-01-30 12:17   ` Fiona Ebner
  0 siblings, 0 replies; 15+ messages in thread
From: Fiona Ebner @ 2025-01-30 12:17 UTC (permalink / raw)
  To: Proxmox VE development discussion, Filip Schauer

Am 29.01.25 um 16:53 schrieb Filip Schauer:
> Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
> ---
>  PVE/QemuServer.pm       |  83 +++---------------------
>  PVE/QemuServer/Makefile |   1 +
>  PVE/QemuServer/RNG.pm   | 135 ++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 145 insertions(+), 74 deletions(-)
>  create mode 100644 PVE/QemuServer/RNG.pm
> 
> diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
> index 5cde94a1..93e65825 100644
> --- a/PVE/QemuServer.pm
> +++ b/PVE/QemuServer.pm
> @@ -61,6 +61,7 @@ use PVE::QemuServer::Memory qw(get_current_memory);
>  use PVE::QemuServer::Monitor qw(mon_cmd);
>  use PVE::QemuServer::PCI qw(print_pci_addr print_pcie_addr print_pcie_root_port parse_hostpci);
>  use PVE::QemuServer::QMPHelpers qw(qemu_deviceadd qemu_devicedel qemu_objectadd qemu_objectdel);
> +use PVE::QemuServer::RNG;
>  use PVE::QemuServer::USB;
>  
>  my $have_sdn;
> @@ -249,39 +250,6 @@ my $spice_enhancements_fmt = {
>      },
>  };
>  
> -my $rng_fmt = {
> -    source => {
> -	type => 'string',
> -	enum => ['/dev/urandom', '/dev/random', '/dev/hwrng'],
> -	default_key => 1,
> -	description => "The file on the host to gather entropy from. In most cases '/dev/urandom'"
> -	    ." should be preferred over '/dev/random' to avoid entropy-starvation issues on the"
> -	    ." host. 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.",
> -    },
> -    max_bytes => {
> -	type => 'integer',
> -	description => "Maximum bytes of entropy allowed to get injected into the guest every"
> -	    ." 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use"
> -	    ." `0` to disable limiting (potentially dangerous!).",
> -	optional => 1,
> -
> -	# default is 1 KiB/s, provides enough entropy to the guest to avoid boot-starvation issues
> -	# (e.g. systemd etc...) while allowing no chance of overwhelming the host, provided we're
> -	# reading from /dev/urandom
> -	default => 1024,
> -    },
> -    period => {
> -	type => 'integer',
> -	description => "Every 'period' milliseconds the entropy-injection quota is reset, allowing"
> -	    ." the guest to retrieve another 'max_bytes' of entropy.",
> -	optional => 1,
> -	default => 1000,
> -    },
> -};
> -
>  my $meta_info_fmt = {
>      'ctime' => {
>  	type => 'integer',

Does not apply, because this got moved recently ;)

> @@ -724,7 +692,7 @@ EODESCR
>      },
>      rng0 => {
>  	type => 'string',
> -	format => $rng_fmt,
> +	format => $PVE::QemuServer::RNG::rng_fmt,
>  	description => "Configure a VirtIO-based Random Number Generator.",
>  	optional => 1,
>      },

Could instead use the standard option you define in the RNG module.

> @@ -2078,16 +2046,6 @@ sub parse_vga {
>      return $res;
>  }
>  
> -sub parse_rng {
> -    my ($value) = @_;
> -
> -    return if !$value;
> -
> -    my $res = eval { parse_property_string($rng_fmt, $value) };
> -    warn $@ if $@;
> -    return $res;
> -}
> -
>  sub parse_meta_info {
>      my ($value) = @_;
> 

Does not apply, because this got moved recently ;)

> @@ -3940,20 +3898,14 @@ sub config_to_command {
>  	}
>      }
>  
> -    my $rng = $conf->{rng0} ? parse_rng($conf->{rng0}) : undef;
> +    my $rng = $conf->{rng0} ? PVE::QemuServer::RNG::parse_rng($conf->{rng0}) : undef;
>      if ($rng && $version_guard->(4, 1, 2)) {
> -	check_rng_source($rng->{source});
> -
> -	my $max_bytes = $rng->{max_bytes} // $rng_fmt->{max_bytes}->{default};
> -	my $period = $rng->{period} // $rng_fmt->{period}->{default};
> -	my $limiter_str = "";
> -	if ($max_bytes) {
> -	    $limiter_str = ",max-bytes=$max_bytes,period=$period";
> -	}
> -
> -	my $rng_addr = print_pci_addr("rng0", $bridges, $arch, $machine_type);
> -	push @$devices, '-object', "rng-random,filename=$rng->{source},id=rng0";
> -	push @$devices, '-device', "virtio-rng-pci,rng=rng0$limiter_str$rng_addr";
> +	my $rng_object = PVE::QemuServer::RNG::print_rng_object('rng0', $rng);
> +	my $rng_device = PVE::QemuServer::RNG::print_rng_device(
> +	    'rng0', $rng, $bridges, $arch, $machine_type
> +	);

Style nit: that's not how multiline function calls are usually wrapped
in our Perl code base:
https://pve.proxmox.com/wiki/Perl_Style_Guide#Wrapping_Arguments

> +	push @$devices, '-object', $rng_object;
> +	push @$devices, '-device', $rng_device;
>      }
>  
>      my $spice_port;

Would be nice to have the moving to a dedicated module be separate from
adding the new helpers.

> @@ -4235,23 +4187,6 @@ sub config_to_command {
>      return wantarray ? ($cmd, $vollist, $spice_port, $pci_devices) : $cmd;
>  }
>  
> -sub check_rng_source {
> -    my ($source) = @_;
> -
> -    # mostly relevant for /dev/hwrng, but doesn't hurt to check others too
> -    die "cannot create VirtIO RNG device: source file '$source' doesn't exist\n"
> -	if ! -e $source;
> -
> -    my $rng_current = '/sys/devices/virtual/misc/hw_random/rng_current';
> -    if ($source eq '/dev/hwrng' && file_read_firstline($rng_current) eq 'none') {
> -	# Needs to abort, otherwise QEMU crashes on first rng access. Note that rng_current cannot
> -	# be changed to 'none' manually, so once the VM is past this point, it's no longer an issue.
> -	die "Cannot start VM with passed-through RNG device: '/dev/hwrng' exists, but"
> -	    ." '$rng_current' is set to 'none'. Ensure that a compatible hardware-RNG is attached"
> -	    ." to the host.\n";
> -    }
> -}
> -
>  sub spice_port {
>      my ($vmid) = @_;
>  
> diff --git a/PVE/QemuServer/Makefile b/PVE/QemuServer/Makefile
> index 89d12091..72c287fc 100644
> --- a/PVE/QemuServer/Makefile
> +++ b/PVE/QemuServer/Makefile
> @@ -1,4 +1,5 @@
>  SOURCES=PCI.pm		\
> +	RNG.pm		\
>  	USB.pm		\
>  	Memory.pm	\
>  	ImportDisk.pm	\
> diff --git a/PVE/QemuServer/RNG.pm b/PVE/QemuServer/RNG.pm
> new file mode 100644
> index 00000000..f7a62f3b
> --- /dev/null
> +++ b/PVE/QemuServer/RNG.pm
> @@ -0,0 +1,135 @@
> +package PVE::QemuServer::RNG;
> +
> +use strict;
> +use warnings;
> +
> +use PVE::QemuServer::PCI qw(print_pci_addr);
> +use PVE::JSONSchema;
> +use PVE::Tools qw(file_read_firstline);
> +use base 'Exporter';

Style nit: The QemuServer::PCI module should be grouped below and I'd
prefer having a blank before it:
https://lore.proxmox.com/pve-devel/e24881cf-bfd2-4063-bde2-99f41031f0f0@proxmox.com/
Having the 'use base' be last is fine, but I'd also prefer a blank
before it.

> +
> +our @EXPORT_OK = qw(
> +parse_rng
> +check_rng_source
> +print_rng_device
> +print_rng_object
> +);
> +
> +our $rng_fmt = {
> +    source => {
> +	type => 'string',
> +	enum => ['/dev/urandom', '/dev/random', '/dev/hwrng'],
> +	default_key => 1,
> +	optional => 1,

Adding the optional should not be part of this patch.

> +	description => "The file on the host to gather entropy from. In most cases '/dev/urandom'"
> +	    ." should be preferred over '/dev/random' to avoid entropy-starvation issues on the"
> +	    ." host. 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.",

The part about /dev/random is outdated as you pointed out in v1 ;)

> +    },
> +    max_bytes => {
> +	type => 'integer',
> +	description => "Maximum bytes of entropy allowed to get injected into the guest every"
> +	    ." 'period' milliseconds. Prefer a lower value when using '/dev/random' as source. Use"
> +	    ." `0` to disable limiting (potentially dangerous!).",


The part about /dev/random is outdated as you pointed out in v1 ;)

> +	optional => 1,
> +
> +	# default is 1 KiB/s, provides enough entropy to the guest to avoid boot-starvation issues
> +	# (e.g. systemd etc...) while allowing no chance of overwhelming the host, provided we're
> +	# reading from /dev/urandom
> +	default => 1024,
> +    },
> +    period => {
> +	type => 'integer',
> +	description => "Every 'period' milliseconds the entropy-injection quota is reset, allowing"
> +	    ." the guest to retrieve another 'max_bytes' of entropy.",
> +	optional => 1,
> +	default => 1000,
> +    },
> +};
> +
> +PVE::JSONSchema::register_format('pve-qm-rng', $rng_fmt);

Since you register the format here, you don't need to make $rng_fmt
shared with 'our' or? (Still need to include the module in QemuServer.pm
to have registering come first).

> +
> +our $rngdesc = {
> +    type => 'string',
> +    format => $rng_fmt,
> +    optional => 1,
> +    description => "Configure a VirtIO-based Random Number Generator.",
> +};
> +PVE::JSONSchema::register_standard_option('pve-qm-rng', $rngdesc);
> +
> +sub parse_rng {
> +    my ($value) = @_;
> +
> +    return if !$value;
> +
> +    my $res = eval { PVE::JSONSchema::parse_property_string($rng_fmt, $value) };
> +    warn $@ if $@;
> +
> +    my $source = $res->{source};

Unused variable, should be part of a later patch.

> +
> +    return $res;
> +}
> +
> +sub check_rng_source {
> +    my ($source) = @_;
> +
> +    # mostly relevant for /dev/hwrng, but doesn't hurt to check others too
> +    die "cannot create VirtIO RNG device: source file '$source' doesn't exist\n"
> +	if ! -e $source;
> +
> +    my $rng_current = '/sys/devices/virtual/misc/hw_random/rng_current';
> +    if ($source eq '/dev/hwrng' && file_read_firstline($rng_current) eq 'none') {
> +	# Needs to abort, otherwise QEMU crashes on first rng access. Note that rng_current cannot
> +	# be changed to 'none' manually, so once the VM is past this point, it's no longer an issue.
> +	die "Cannot start VM with passed-through RNG device: '/dev/hwrng' exists, but"
> +	    ." '$rng_current' is set to 'none'. Ensure that a compatible hardware-RNG is attached"
> +	    ." to the host.\n";
> +    }
> +}
> +
> +sub get_rng_source_path {
> +    my ($rng) = @_;
> +
> +    my $source = $rng->{source};
> +
> +    if (defined($source)) {
> +	return $source;
> +    }
> +
> +    return;
> +}
> +
> +sub print_rng_device {

I'd add _commandline to reduce potential for confusion

> +    my ($id, $rng, $bridges, $arch, $machine) = @_;
> +
> +    return if !$rng;

Isn't failing better? IMHO caller should first check that it has
something to print rather than check the result.

> +
> +    my $source_path = get_rng_source_path($rng);
> +    check_rng_source($source_path);

Since the source is not part of the result, maybe not check it here, but
only in print_rng_object()?

> +
> +    my $max_bytes = $rng->{max_bytes} // $rng_fmt->{max_bytes}->{default};
> +    my $period = $rng->{period} // $rng_fmt->{period}->{default};
> +    my $limiter_str = "";
> +    if ($max_bytes) {
> +	$limiter_str = ",max-bytes=$max_bytes,period=$period";
> +    }
> +
> +    my $rng_addr = print_pci_addr($id, $bridges, $arch, $machine);
> +
> +    return "virtio-rng-pci,rng=$id$limiter_str$rng_addr";
> +}
> +
> +sub print_rng_object {

I'd add _commandline to reduce potential for confusion

> +    my ($id, $rng) = @_;
> +
> +    return if !$rng;

Isn't failing better? IMHO caller should first check that it has
something to print rather than check the result.

> +
> +    my $source_path = get_rng_source_path($rng);
> +    check_rng_source($source_path);
> +
> +    return "rng-random,filename=$source_path,id=$id";
> +}
> +
> +1;



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [pve-devel] [PATCH qemu-server v2 8/9] allow non-root users to set /dev/u?random as an RNG source
  2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 8/9] allow non-root users to set /dev/u?random as an RNG source Filip Schauer
@ 2025-01-30 12:18   ` Fiona Ebner
  0 siblings, 0 replies; 15+ messages in thread
From: Fiona Ebner @ 2025-01-30 12:18 UTC (permalink / raw)
  To: Proxmox VE development discussion, Filip Schauer

Am 29.01.25 um 16:53 schrieb Filip Schauer:
> Allow non-root users with the VM.Config.HWType privilege to configure
> /dev/urandom & /dev/random as an entropy source for a VirtIO RNG device.
> /dev/hwrng remains restricted to the root user.
> 
> Signed-off-by: Filip Schauer <f.schauer@proxmox.com>
> ---
>  PVE/API2/Qemu.pm  | 42 ++++++++++++++++++++++++++++++++++++++++++
>  PVE/QemuServer.pm | 13 +++++++++++--
>  2 files changed, 53 insertions(+), 2 deletions(-)
> 
> diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
> index db356b7e..8262c9d4 100644
> --- a/PVE/API2/Qemu.pm
> +++ b/PVE/API2/Qemu.pm
> @@ -670,6 +670,7 @@ my $hwtypeoptions = {
>      'vga' => 1,
>      'watchdog' => 1,
>      'audio0' => 1,
> +    'rng0' => 1,
>  };
>  
>  my $generaloptions = {
> @@ -798,6 +799,36 @@ my sub check_vm_create_hostpci_perm {
>      return 1;
>  };
>  
> +my sub check_rng_perm {
> +    my ($rpcenv, $authuser, $vmid, $pool, $opt, $value) = @_;
> +
> +    return 1 if $authuser eq 'root@pam';
> +
> +    $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.HWType']);
> +
> +    my $device = PVE::JSONSchema::parse_property_string('pve-qm-rng', $value);

Nit: missing explicit use statement for the RNG module (that is where
the format is registered).


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [pve-devel] [PATCH guest-common v2 1/9] mapping: add a hardware RNG mapping config
  2025-01-29 15:53 ` [pve-devel] [PATCH guest-common v2 1/9] mapping: add a hardware RNG mapping config Filip Schauer
@ 2025-01-30 12:18   ` Fiona Ebner
  0 siblings, 0 replies; 15+ messages in thread
From: Fiona Ebner @ 2025-01-30 12:18 UTC (permalink / raw)
  To: Proxmox VE development discussion, Filip Schauer

Am 29.01.25 um 16:53 schrieb Filip Schauer:
> +my $map_fmt = {
> +    node => get_standard_option('pve-node'),
> +    path => {
> +	description => "The path to the device node of the entropy source.",
> +	type => 'string',
> +	pattern => qr/^\/dev\/.+$/,

Style nit: could use | or ! as the regex delimiter to improve readability

Can we restrict this up-front somehow? I'd even be inclined to start out
with the enum we had in qemu-server. A generic path below /dev seems
prone to abuse at a first glance. Mapping.Modify for hardware RNG should
not ease access to other devices. And the check_rng_source() doesn't
currently offer any real protection either (just restricts the
/dev/hwrng case).


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user
  2025-01-30 12:17 ` [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Fiona Ebner
@ 2025-02-10 15:47   ` Filip Schauer
  0 siblings, 0 replies; 15+ messages in thread
From: Filip Schauer @ 2025-02-10 15:47 UTC (permalink / raw)
  To: Fiona Ebner, Proxmox VE development discussion

Superseded by:
https://lore.proxmox.com/pve-devel/20250210153734.103381-1-f.schauer@proxmox.com/

On 30/01/2025 13:17, Fiona Ebner wrote:
> It's a lot of overhead for a very specific kind of device. What irks me
> is that we have a lot of boilerplate duplication for each new mapping
> type, also for the API endpoints. Nothing specific to your series of
> course, but maybe something we could/should address?

Agree

On 30/01/2025 13:17, Fiona Ebner wrote:
> In the UI, it
> probably would also be better to have a separate view for each mapping
> type?

I split resource mapping types into tabbed views in v3.

On 30/01/2025 13:17, Fiona Ebner wrote:
> When I try to add a mapping in the UI, I get
> Parameter verification failed. (400)
> map: type check ('array') failed

Fixed in v3



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2025-02-10 15:47 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-29 15:53 [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH guest-common v2 1/9] mapping: add a hardware RNG mapping config Filip Schauer
2025-01-30 12:18   ` Fiona Ebner
2025-01-29 15:53 ` [pve-devel] [PATCH cluster v2 2/9] cfs: add 'mapping/hwrng.cfg' to observed files Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 3/9] introduce hardware rng mapping api Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 4/9] introduce hardware rng scanning api Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 5/9] ui: add hardware RNG resource mapping Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH manager v2 6/9] ui: allow use of mapped hardware RNGs as entropy sources for VMs Filip Schauer
2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 7/9] refactor: move rng related code into its own module Filip Schauer
2025-01-30 12:17   ` Fiona Ebner
2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 8/9] allow non-root users to set /dev/u?random as an RNG source Filip Schauer
2025-01-30 12:18   ` Fiona Ebner
2025-01-29 15:53 ` [pve-devel] [PATCH qemu-server v2 9/9] let VirtIO RNG devices source entropy from mapped HWRNGs Filip Schauer
2025-01-30 12:17 ` [pve-devel] [PATCH cluster/guest-common/manager/qemu-server v2 0/9] fix #5657: allow configuring RNG device as non-root user Fiona Ebner
2025-02-10 15:47   ` Filip Schauer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal