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)
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