NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/58632 (getentropy(2) and arc4random(3) do not reseed on VM fork)



Thank you for the quick patch, awesome work!

One more thing: would it make sense to mention this in the man page for arc4random and getentropy? For context, I’m implementing random number generation in the Rust standard library (see https://github.com/rust-lang/rust/pull/129201), and the library team would quite like to make sure that the system sources we use protect against VM forks (https://github.com/rust-lang/rust/pull/129201#issuecomment-2302563968), so having this as an explicit guarantee on NetBSD would ease some concerns.

On 25. Aug 2024, at 22:52, Taylor R Campbell <riastradh%NetBSD.org@localhost> wrote:

The attached patch addresses part of the problem.

There are some other parts to address -- noted in the man page for the
new acpivmgenid(4) driver -- which I'll pick up later.
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1724594231 0
#      Sun Aug 25 13:57:11 2024 +0000
# Branch trunk
# Node ID 5be00488683c99f21ab86a2ae2106bacf7f3888a
# Parent  cf7a8f9687ea781207542c43a006460dc134ea3b
# EXP-Topic riastradh-pr58632-vmgenid
acpivmgenid(4): New driver for virtual machine generation ID.

Added to amd64/ALL and i386/ALL kernel configurations, and made
available as a loadable module acpivmgenid.kmod on x86, for now.

TBD: Add to all ACPI-supporting GENERIC kernels.

PR kern/58632: getentropy(2) and arc4random(3) do not reseed on VM
fork

diff -r cf7a8f9687ea -r 5be00488683c distrib/sets/lists/man/mi
--- a/distrib/sets/lists/man/mi	Sat Aug 24 07:24:34 2024 +0000
+++ b/distrib/sets/lists/man/mi	Sun Aug 25 13:57:11 2024 +0000
@@ -834,6 +834,7 @@
 ./usr/share/man/cat4/acpismbus.0		man-sys-catman		.cat
 ./usr/share/man/cat4/acpitz.0			man-sys-catman		.cat
 ./usr/share/man/cat4/acpivga.0			man-sys-catman		.cat
+./usr/share/man/cat4/acpivmgenid.0		man-sys-catman		.cat
 ./usr/share/man/cat4/acpiwdrt.0			man-sys-catman		.cat
 ./usr/share/man/cat4/acpiwmi.0			man-sys-catman		.cat
 ./usr/share/man/cat4/adb.0			man-sys-catman		.cat
@@ -4391,6 +4392,7 @@
 ./usr/share/man/man4/acpismbus.4		man-sys-man		.man
 ./usr/share/man/man4/acpitz.4			man-sys-man		.man
 ./usr/share/man/man4/acpivga.4			man-sys-man		.man
+./usr/share/man/man4/acpivmgenid.4		man-sys-man		.man
 ./usr/share/man/man4/acpiwdrt.4			man-sys-man		.man
 ./usr/share/man/man4/acpiwmi.4			man-sys-man		.man
 ./usr/share/man/man4/adb.4			man-sys-man		.man
diff -r cf7a8f9687ea -r 5be00488683c distrib/sets/lists/manhtml/mi
--- a/distrib/sets/lists/manhtml/mi	Sat Aug 24 07:24:34 2024 +0000
+++ b/distrib/sets/lists/manhtml/mi	Sun Aug 25 13:57:11 2024 +0000
@@ -755,6 +755,7 @@
 ./usr/share/man/html4/acpismbus.html		man-sys-htmlman		html
 ./usr/share/man/html4/acpitz.html		man-sys-htmlman		html
 ./usr/share/man/html4/acpivga.html		man-sys-htmlman		html
+./usr/share/man/html4/acpivmgenid.html		man-sys-htmlman		html
 ./usr/share/man/html4/acpiwdrt.html		man-sys-htmlman		html
 ./usr/share/man/html4/acpiwmi.html		man-sys-htmlman		html
 ./usr/share/man/html4/adb.html			man-sys-htmlman		html
diff -r cf7a8f9687ea -r 5be00488683c distrib/sets/lists/modules/md.amd64
--- a/distrib/sets/lists/modules/md.amd64	Sat Aug 24 07:24:34 2024 +0000
+++ b/distrib/sets/lists/modules/md.amd64	Sun Aug 25 13:57:11 2024 +0000
@@ -24,6 +24,8 @@
 ./@MODULEDIR@/acpiverbose/acpiverbose.kmod	modules-base-kernel	kmod
 ./@MODULEDIR@/acpivga				modules-base-kernel	kmod
 ./@MODULEDIR@/acpivga/acpivga.kmod		modules-base-kernel	kmod
+./@MODULEDIR@/acpivmgenid			modules-base-kernel	kmod
+./@MODULEDIR@/acpivmgenid/acpivmgenid.kmod	modules-base-kernel	kmod
 ./@MODULEDIR@/acpiwdrt				modules-base-kernel	kmod
 ./@MODULEDIR@/acpiwdrt/acpiwdrt.kmod		modules-base-kernel	kmod
 ./@MODULEDIR@/acpiwmi				modules-base-kernel	kmod
diff -r cf7a8f9687ea -r 5be00488683c distrib/sets/lists/modules/md.i386
--- a/distrib/sets/lists/modules/md.i386	Sat Aug 24 07:24:34 2024 +0000
+++ b/distrib/sets/lists/modules/md.i386	Sun Aug 25 13:57:11 2024 +0000
@@ -24,6 +24,8 @@
 ./@MODULEDIR@/acpiverbose/acpiverbose.kmod	modules-base-kernel	kmod
 ./@MODULEDIR@/acpivga				modules-base-kernel	kmod
 ./@MODULEDIR@/acpivga/acpivga.kmod		modules-base-kernel	kmod
+./@MODULEDIR@/acpivmgenid			modules-base-kernel	kmod
+./@MODULEDIR@/acpivmgenid/acpivmgenid.kmod	modules-base-kernel	kmod
 ./@MODULEDIR@/acpiwdrt				modules-base-kernel	kmod
 ./@MODULEDIR@/acpiwdrt/acpiwdrt.kmod		modules-base-kernel	kmod
 ./@MODULEDIR@/acpiwmi				modules-base-kernel	kmod
diff -r cf7a8f9687ea -r 5be00488683c share/man/man4/Makefile
--- a/share/man/man4/Makefile	Sat Aug 24 07:24:34 2024 +0000
+++ b/share/man/man4/Makefile	Sun Aug 25 13:57:11 2024 +0000
@@ -100,7 +100,8 @@ MAN+=	irframe.4 cir.4 irframetty.4 oboe.
 # ACPI devices
 MAN+=	acpi.4 acpiacad.4 acpibat.4 acpibut.4 acpicpu.4 \
 	acpidalb.4 acpiec.4 acpifan.4 acpihed.4 acpilid.4 \
-	acpipmtr.4 acpismbus.4 acpitz.4 acpivga.4 acpiwdrt.4 acpiwmi.4
+	acpipmtr.4 acpismbus.4 acpitz.4 acpivga.4 acpivmgenid.4 \
+	acpiwdrt.4 acpiwmi.4
 MAN+=	apei.4
 
 # Radio devices
diff -r cf7a8f9687ea -r 5be00488683c share/man/man4/acpivmgenid.4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/share/man/man4/acpivmgenid.4	Sun Aug 25 13:57:11 2024 +0000
@@ -0,0 +1,112 @@
+.\"	$NetBSD$
+.\"
+.\" Copyright (c) 2024 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd August 25, 2024
+.Dt ACPIVMGENID 4
+.Os
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh NAME
+.Nm acpivmgenid
+.Nd ACPI Virtual Machine Generation ID
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh SYNOPSIS
+.Cd "acpivmgenid* at acpi?"
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh DESCRIPTION
+.Nm
+provides a generation ID for virtual machines.
+.Pp
+When starting two otherwise identical virtual machines, whether from
+the same clean image or by cloning snapshots or any other mechanism,
+the VM host may choose a different generation ID.
+Although this generation ID is not secret, it is incorporated into the
+.Xr entropy 7
+pool (with a measure of zero entropy) so that the two virtual machines
+will produce independent random output.
+.Pp
+If a live VM is cloned, the VM host may change the generation ID in one
+or both of the clones and notify them through the
+.Nm
+device.
+When this happens,
+.Nx
+will reseed system random number generators, so that output of
+.Pa /dev/urandom
+and
+.Xr getentropy 3
+will be independent in the two clones.
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh SYSCTLS
+The following
+.Xr sysctl 7
+nodes are available:
+.Bl -tag -width Li
+.It Li "hw.acpivmgenid" Ns Va N Ns Li ".id"
+The current 16-byte VM generation ID.
+.It Li "hw.acpivmgenid" Ns Va N Ns Li ".paddr"
+The physical address of the VM generation ID provided by the host.
+.El
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh SEE ALSO
+.Xr arc4random 3 ,
+.Xr getentropy 3 ,
+.Xr rnd 4 ,
+.Xr entropy 7
+.Rs
+.%T Virtual Machine Generation ID
+.%Q Microsoft
+.%D 2018-08-01
+.%U http://go.microsoft.com/fwlink/?LinkId=260709
+.Re
+.Rs
+.%T Virtual Machine Generation ID Device
+.%Q The QEMU Project Developers
+.%U https://www.qemu.org/docs/master/specs/vmgenid.html
+.Re
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh HISTORY
+The
+.Nm
+driver first appeared in
+.Nx 11.0 .
+.\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.Sh BUGS
+Currently
+.Nx
+does not request fresh samples from all on-demand entropy sources when
+the VM generation ID changes, so although the outputs of the system
+entropy pool appear independent to an outside observer, disclosing the
+kernel memory of one VM clone to an adversary may allow the adversary
+to predict another VM clone's
+.Pa /dev/urandom
+outputs.
+.Pp
+Currently
+.Xr arc4random 3
+is not reseeded when the VM generation ID changes.
+.Pp
+Currently there is no cheaper way to detect VM generation ID changes
+than to query sysctl.
diff -r cf7a8f9687ea -r 5be00488683c sys/arch/amd64/conf/ALL
--- a/sys/arch/amd64/conf/ALL	Sat Aug 24 07:24:34 2024 +0000
+++ b/sys/arch/amd64/conf/ALL	Sun Aug 25 13:57:11 2024 +0000
@@ -381,6 +381,7 @@ acpismbus*	at acpi?		# ACPI SMBus CMI (e
 acpitz* 	at acpi?		# ACPI Thermal Zone
 acpivga*	at acpi?		# ACPI Display Adapter
 acpiout*	at acpivga?		# ACPI Display Output Device
+acpivmgenid*	at acpi?		# ACPI Virtual Machine Generation ID
 acpiwdrt*	at acpi?		# ACPI Watchdog Resource Table
 acpiwmi*	at acpi?		# ACPI WMI Mapper
 apei*		at apeibus?		# ACPI Platform Error Interfaces
diff -r cf7a8f9687ea -r 5be00488683c sys/arch/i386/conf/ALL
--- a/sys/arch/i386/conf/ALL	Sat Aug 24 07:24:34 2024 +0000
+++ b/sys/arch/i386/conf/ALL	Sun Aug 25 13:57:11 2024 +0000
@@ -368,6 +368,7 @@ acpismbus*	at acpi?		# ACPI SMBus CMI (e
 acpitz* 	at acpi?		# ACPI Thermal Zone
 acpivga*	at acpi?		# ACPI Display Adapter
 acpiout*	at acpivga?		# ACPI Display Output Device
+acpivmgenid*	at acpi?		# ACPI Virtual Machine Generation ID
 acpiwdrt*	at acpi?		# ACPI Watchdog Resource Table
 acpiwmi*	at acpi?		# ACPI WMI Mapper
 apei*		at apeibus?		# ACPI Platform Error Interfaces
diff -r cf7a8f9687ea -r 5be00488683c sys/dev/acpi/acpi_vmgenid.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/acpi/acpi_vmgenid.c	Sun Aug 25 13:57:11 2024 +0000
@@ -0,0 +1,346 @@
+/*	$NetBSD$	*/
+
+/*-
+ * Copyright (c) 2024 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Virtual Machine Generation ID
+ *
+ *	The VMGENID is an 8-byte cookie shared between a VM host and VM
+ *	guest.  Whenever the host clones a VM, it changes the VMGENID
+ *	and sends an ACPI notification to the guest.
+ *
+ * References:
+ *
+ *	`Virtual Machine Generation ID', Microsoft, 2012-08-01.
+ *	http://go.microsoft.com/fwlink/?LinkId=260709
+ *
+ *	`Virtual Machine Generation ID Device', The QEMU Project
+ *	Developers.
+ *	https://www.qemu.org/docs/master/specs/vmgenid.html
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/device.h>
+#include <sys/entropy.h>
+#include <sys/module.h>
+#include <sys/rndsource.h>
+#include <sys/sysctl.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+
+#define	_COMPONENT	ACPI_RESOURCE_COMPONENT
+ACPI_MODULE_NAME	("acpi_vmgenid")
+
+struct acpivmgenid {
+	uint8_t		id[16];
+} __aligned(8);
+
+struct acpivmgenid_softc {
+	device_t			sc_dev;
+	struct acpi_devnode		*sc_node;
+	uint64_t			sc_paddr;
+	struct acpivmgenid		*sc_vaddr;
+	struct acpivmgenid		sc_cur;
+	struct krndsource		sc_rndsource;
+	struct sysctllog		*sc_sysctllog;
+	const struct sysctlnode		*sc_sysctlroot;
+};
+
+static int acpivmgenid_match(device_t, cfdata_t, void *);
+static void acpivmgenid_attach(device_t, device_t, void *);
+static int acpivmgenid_detach(device_t, int);
+static void acpivmgenid_set(struct acpivmgenid_softc *, const char *);
+static void acpivmgenid_notify(ACPI_HANDLE, uint32_t, void *);
+static void acpivmgenid_reset(void *);
+static int acpivmgenid_sysctl(SYSCTLFN_ARGS);
+
+static const struct device_compatible_entry compat_data[] = {
+	{ .compat = "VM_Gen_Counter" },		/* from the Microsoft spec */
+	{ .compat = "VM_GEN_COUNTER" },		/* used by qemu */
+	{ .compat = "VMGENCTR" },		/* recognized by Linux */
+	DEVICE_COMPAT_EOL
+};
+
+CFATTACH_DECL_NEW(acpivmgenid, sizeof(struct acpivmgenid_softc),
+    acpivmgenid_match, acpivmgenid_attach, acpivmgenid_detach, NULL);
+
+static int
+acpivmgenid_match(device_t parent, cfdata_t match, void *aux)
+{
+	const struct acpi_attach_args *const aa = aux;
+
+	return acpi_compatible_match(aa, compat_data);
+}
+
+static void
+acpivmgenid_attach(device_t parent, device_t self, void *aux)
+{
+	struct acpivmgenid_softc *const sc = device_private(self);
+	const struct acpi_attach_args *const aa = aux;
+	ACPI_BUFFER addrbuf = {
+		.Pointer = NULL,
+		.Length = ACPI_ALLOCATE_BUFFER,
+	};
+	ACPI_OBJECT *addrobj, *addrarr;
+	ACPI_STATUS rv;
+	int error;
+
+	aprint_naive(": ACPI VM Generation ID\n");
+	aprint_normal(": ACPI VM Generation ID\n");
+
+	sc->sc_dev = self;
+	sc->sc_node = aa->aa_node;
+
+	/*
+	 * Get the address from the ADDR object, which is a package of
+	 * two 32-bit integers representing the low and high halves of
+	 * a 64-bit physical address.
+	 */
+	rv = AcpiEvaluateObjectTyped(sc->sc_node->ad_handle, "ADDR", NULL,
+	    &addrbuf, ACPI_TYPE_PACKAGE);
+	if (ACPI_FAILURE(rv)) {
+		aprint_error_dev(self, "failed to get ADDR: %s\n",
+		    AcpiFormatException(rv));
+		goto out;
+	}
+	addrobj = addrbuf.Pointer;
+	if (addrobj->Type != ACPI_TYPE_PACKAGE ||
+	    addrobj->Package.Count != 2) {
+		aprint_error_dev(self, "invalid ADDR\n");
+		goto out;
+	}
+	addrarr = addrobj->Package.Elements;
+	if (addrarr[0].Type != ACPI_TYPE_INTEGER ||
+	    addrarr[1].Type != ACPI_TYPE_INTEGER ||
+	    addrarr[0].Integer.Value > UINT32_MAX ||
+	    addrarr[1].Integer.Value > UINT32_MAX) {
+		aprint_error_dev(self, "invalid ADDR\n");
+		goto out;
+	}
+	sc->sc_paddr = (ACPI_PHYSICAL_ADDRESS)addrarr[0].Integer.Value;
+	sc->sc_paddr |= (ACPI_PHYSICAL_ADDRESS)addrarr[1].Integer.Value << 32;
+	aprint_normal_dev(self, "paddr=0x%"PRIx64"\n", (uint64_t)sc->sc_paddr);
+
+	/*
+	 * Map the physical address into virtual address space.
+	 */
+	sc->sc_vaddr = AcpiOsMapMemory(sc->sc_paddr, sizeof(*sc->sc_vaddr));
+	if (sc->sc_vaddr == NULL) {
+		aprint_error_dev(self, "failed to map address\n");
+		goto out;
+	}
+
+	/*
+	 * Register a random source so we can attribute samples.
+	 */
+	rnd_attach_source(&sc->sc_rndsource, device_xname(self),
+	    RND_TYPE_UNKNOWN, RND_FLAG_COLLECT_TIME|RND_FLAG_COLLECT_VALUE);
+
+	/*
+	 * Register an ACPI notifier so that we can detect changes.
+	 */
+	(void)acpi_register_notify(sc->sc_node, acpivmgenid_notify);
+
+	/*
+	 * Now that we have registered a random source and a notifier,
+	 * read out the first value.
+	 */
+	acpivmgenid_set(sc, "initial");
+
+	/*
+	 * Attach a sysctl tree, rooted at hw.acpivmgenidN.
+	 */
+	error = sysctl_createv(&sc->sc_sysctllog, 0, NULL, &sc->sc_sysctlroot,
+	    CTLFLAG_PERMANENT, CTLTYPE_NODE, device_xname(self),
+	    SYSCTL_DESCR("Virtual Machine Generation ID device"),
+	    NULL, 0, NULL, 0,
+	    CTL_HW, CTL_CREATE, CTL_EOL);
+	if (error) {
+		aprint_error_dev(self, "failed to create sysctl hw.%s: %d\n",
+		    device_xname(self), error);
+		goto out;
+	}
+
+	/*
+	 * hw.acpivmgenidN.id (`struct', 16-byte array)
+	 */
+	error = sysctl_createv(&sc->sc_sysctllog, 0, &sc->sc_sysctlroot, NULL,
+	    CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_PRIVATE, CTLTYPE_STRUCT,
+	    "id", SYSCTL_DESCR("Virtual Machine Generation ID device"),
+	    &acpivmgenid_sysctl, 0, sc, sizeof(struct acpivmgenid),
+	    CTL_CREATE, CTL_EOL);
+	if (error) {
+		aprint_error_dev(self,
+		    "failed to create sysctl hw.%s.id: %d\n",
+		    device_xname(self), error);
+		goto out;
+	}
+
+	/*
+	 * hw.acpivmgenidN.paddr (64-bit integer)
+	 */
+	__CTASSERT(sizeof(ACPI_PHYSICAL_ADDRESS) == sizeof(long));
+	error = sysctl_createv(&sc->sc_sysctllog, 0, &sc->sc_sysctlroot, NULL,
+	    CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_PRIVATE, CTLTYPE_LONG,
+	    "paddr", SYSCTL_DESCR("Virtual Machine Generation ID device"),
+	    NULL, 0, &sc->sc_paddr, sizeof(sc->sc_paddr),
+	    CTL_CREATE, CTL_EOL);
+	if (error) {
+		aprint_error_dev(self,
+		    "failed to create sysctl hw.%s.paddr: %d\n",
+		    device_xname(self), error);
+		goto out;
+	}
+
+out:	ACPI_FREE(addrbuf.Pointer);
+}
+
+static int
+acpivmgenid_detach(device_t self, int flags)
+{
+	struct acpivmgenid_softc *const sc = device_private(self);
+	int error;
+
+	error = config_detach_children(self, flags);
+	if (error)
+		return error;
+
+	sysctl_teardown(&sc->sc_sysctllog);
+	acpi_deregister_notify(sc->sc_node);
+	rnd_detach_source(&sc->sc_rndsource);
+	if (sc->sc_vaddr) {
+		AcpiOsUnmapMemory(sc->sc_vaddr, sizeof(*sc->sc_vaddr));
+		sc->sc_vaddr = NULL;	/* paranoia */
+	}
+	sc->sc_paddr = 0;	/* paranoia */
+
+	return 0;
+}
+
+static void
+acpivmgenid_set(struct acpivmgenid_softc *sc, const char *prefix)
+{
+	struct acpivmgenid vmgenid;
+	char vmgenidstr[2*__arraycount(vmgenid.id) + 1];
+	unsigned i;
+
+	/*
+	 * Grab the current VM generation ID.  No obvious way to make
+	 * this atomic, so let's hope if it changes in the middle we'll
+	 * get another notification.
+	 */
+	memcpy(&vmgenid, sc->sc_vaddr, sizeof(vmgenid));
+
+	/*
+	 * Print the VM generation ID to the console for posterity.
+	 */
+	for (i = 0; i < __arraycount(vmgenid.id); i++) {
+		vmgenidstr[2*i] = "0123456789abcdef"[vmgenid.id[i] >> 4];
+		vmgenidstr[2*i + 1] = "0123456789abcdef"[vmgenid.id[i] & 0xf];
+	}
+	vmgenidstr[2*sizeof(vmgenid)] = '\0';
+	aprint_verbose_dev(sc->sc_dev, "%s: %s\n", prefix, vmgenidstr);
+
+	/*
+	 * Enter the new VM generation ID into the entropy pool.
+	 */
+	rnd_add_data(&sc->sc_rndsource, &vmgenid, sizeof(vmgenid), 0);
+}
+
+static void
+acpivmgenid_notify(ACPI_HANDLE hdl, uint32_t notify, void *opaque)
+{
+	const device_t self = opaque;
+	struct acpivmgenid_softc *const sc = device_private(self);
+
+	if (notify != 0x80) {
+		aprint_debug_dev(self, "unknown notify 0x%02x\n", notify);
+		return;
+	}
+
+	(void)AcpiOsExecute(OSL_NOTIFY_HANDLER, &acpivmgenid_reset, sc);
+}
+
+static void
+acpivmgenid_reset(void *cookie)
+{
+	struct acpivmgenid_softc *const sc = cookie;
+
+	/*
+	 * Grab the current VM generation ID to put it into the entropy
+	 * pool; then force consolidation so it affects all subsequent
+	 * draws from the entropy pool and the entropy epoch advances.
+	 *
+	 * XXX This should also reset the entropy count and request new
+	 * samples from all sources, but there currently isn't a good
+	 * way to do that after boot.
+	 */
+	acpivmgenid_set(sc, "cloned");
+	entropy_consolidate();
+}
+
+static int
+acpivmgenid_sysctl(SYSCTLFN_ARGS)
+{
+	struct sysctlnode node = *rnode;
+	struct acpivmgenid_softc *const sc = node.sysctl_data;
+
+	node.sysctl_data = sc->sc_vaddr;
+	return sysctl_lookup(SYSCTLFN_CALL(&node));
+}
+
+MODULE(MODULE_CLASS_DRIVER, acpivmgenid, NULL);
+
+#ifdef _MODULE
+#include "ioconf.c"
+#endif
+
+static int
+acpivmgenid_modcmd(modcmd_t cmd, void *opaque)
+{
+	int error = 0;
+
+	switch (cmd) {
+	case MODULE_CMD_INIT:
+#ifdef _MODULE
+		error = config_init_component(cfdriver_ioconf_acpivmgenid,
+		    cfattach_ioconf_acpivmgenid, cfdata_ioconf_acpivmgenid);
+#endif
+		return error;
+	case MODULE_CMD_FINI:
+#ifdef _MODULE
+		error = config_fini_component(cfdriver_ioconf_acpivmgenid,
+		    cfattach_ioconf_acpivmgenid, cfdata_ioconf_acpivmgenid);
+#endif
+		return error;
+	default:
+		return ENOTTY;
+	}
+}
diff -r cf7a8f9687ea -r 5be00488683c sys/dev/acpi/files.acpi
--- a/sys/dev/acpi/files.acpi	Sat Aug 24 07:24:34 2024 +0000
+++ b/sys/dev/acpi/files.acpi	Sun Aug 25 13:57:11 2024 +0000
@@ -116,6 +116,11 @@ device	acpicppc: acpipcc
 attach	acpicppc at acpinodebus
 file	dev/acpi/acpi_cppc.c		acpicppc
 
+# ACPI Virtual Machine Generation ID
+device	acpivmgenid
+attach	acpivmgenid at acpinodebus
+file	dev/acpi/acpi_vmgenid.c		acpivmgenid
+
 # ACPI Platform Error Interface
 device	apei
 attach	apei at apeibus
diff -r cf7a8f9687ea -r 5be00488683c sys/modules/Makefile
--- a/sys/modules/Makefile	Sat Aug 24 07:24:34 2024 +0000
+++ b/sys/modules/Makefile	Sun Aug 25 13:57:11 2024 +0000
@@ -298,6 +298,7 @@ SUBDIR+=	acpilid
 SUBDIR+=	acpipmtr
 SUBDIR+=	acpitz
 SUBDIR+=	acpivga
+SUBDIR+=	acpivmgenid
 SUBDIR+=	acpiwdrt
 SUBDIR+=	acpiwmi
 SUBDIR+=	aibs
diff -r cf7a8f9687ea -r 5be00488683c sys/modules/acpivmgenid/Makefile
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/modules/acpivmgenid/Makefile	Sun Aug 25 13:57:11 2024 +0000
@@ -0,0 +1,11 @@
+#	$NetBSD$
+
+.include "../Makefile.inc"
+
+.PATH:	${S}/dev/acpi
+
+KMOD=	acpivmgenid
+IOCONF=	acpivmgenid.ioconf
+SRCS=	acpi_vmgenid.c
+
+.include <bsd.kmodule.mk>
diff -r cf7a8f9687ea -r 5be00488683c sys/modules/acpivmgenid/acpivmgenid.ioconf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/modules/acpivmgenid/acpivmgenid.ioconf	Sun Aug 25 13:57:11 2024 +0000
@@ -0,0 +1,10 @@
+#	$NetBSD$
+
+ioconf acpivmgenid
+
+include "conf/files"
+include "dev/acpi/files.acpi"
+
+pseudo-root acpi*
+
+acpivmgenid*	at acpi?
# HG changeset patch
# User Taylor R Campbell <riastradh%NetBSD.org@localhost>
# Date 1724594459 0
#      Sun Aug 25 14:00:59 2024 +0000
# Branch trunk
# Node ID 1209429d9c2f1be453574307f2a1b7021ff1bfbd
# Parent  5be00488683c99f21ab86a2ae2106bacf7f3888a
# EXP-Topic riastradh-pr58632-vmgenid
amd64, evbarm, i386: Add acpivmgenid(4) to GENERIC.

PR kern/58632: getentropy(2) and arc4random(3) do not reseed on VM
fork

diff -r 5be00488683c -r 1209429d9c2f sys/arch/amd64/conf/GENERIC
--- a/sys/arch/amd64/conf/GENERIC	Sun Aug 25 13:57:11 2024 +0000
+++ b/sys/arch/amd64/conf/GENERIC	Sun Aug 25 14:00:59 2024 +0000
@@ -341,6 +341,7 @@ acpilid*	at acpi?		# ACPI Lid Switch
 acpitz* 	at acpi?		# ACPI Thermal Zone
 acpivga*	at acpi?		# ACPI Display Adapter
 acpiout*	at acpivga?		# ACPI Display Output Device
+acpivmgenid*	at acpi?		# ACPI Virtual Machine Generation ID
 acpiwdrt*	at acpi?		# ACPI Watchdog Resource Table
 acpiwmi*	at acpi?		# ACPI WMI Mapper
 apei*		at apeibus?		# ACPI Platform Error Interfaces
diff -r 5be00488683c -r 1209429d9c2f sys/arch/evbarm/conf/GENERIC64
--- a/sys/arch/evbarm/conf/GENERIC64	Sun Aug 25 13:57:11 2024 +0000
+++ b/sys/arch/evbarm/conf/GENERIC64	Sun Aug 25 14:00:59 2024 +0000
@@ -127,6 +127,7 @@ acpifan*	at acpi?
 acpiged*	at acpi?
 acpilid*	at acpi?
 acpitz* 	at acpi?
+acpivmgenid*	at acpi?
 
 # CPUs
 cpus*		at fdt? pass 0
diff -r 5be00488683c -r 1209429d9c2f sys/arch/i386/conf/GENERIC
--- a/sys/arch/i386/conf/GENERIC	Sun Aug 25 13:57:11 2024 +0000
+++ b/sys/arch/i386/conf/GENERIC	Sun Aug 25 14:00:59 2024 +0000
@@ -324,6 +324,7 @@ acpilid*	at acpi?		# ACPI Lid Switch
 acpitz* 	at acpi?		# ACPI Thermal Zone
 acpivga*	at acpi?		# ACPI Display Adapter
 acpiout*	at acpivga?		# ACPI Display Output Device
+acpivmgenid*	at acpi?		# ACPI Virtual Machine Generation ID
 acpiwdrt*	at acpi?		# ACPI Watchdog Resource Table
 acpiwmi*	at acpi?		# ACPI WMI Mapper
 apei*		at apeibus?		# ACPI Platform Error Interfaces



Home | Main Index | Thread Index | Old Index