public inbox for pve-devel@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal