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 following reply was made to PR kern/58632; it has been noted by GNATS.

From: =?utf-8?Q?Jonas_B=C3=B6ttiger?= <jonas.boettiger%icloud.com@localhost>
To: Taylor R Campbell <riastradh%NetBSD.org@localhost>
Cc: "gnats-bugs%netbsd.org@localhost" <gnats-bugs%NetBSD.org@localhost>,
 "netbsd-bugs%netbsd.org@localhost" <netbsd-bugs%NetBSD.org@localhost>
Subject: Re: kern/58632 (getentropy(2) and arc4random(3) do not reseed on VM
 fork)
Date: Tue, 27 Aug 2024 12:28:11 +0200

 --Apple-Mail=_8F5D9F90-5683-49D7-B788-791C1D0129CA
 Content-Transfer-Encoding: quoted-printable
 Content-Type: text/plain;
 	charset=utf-8
 
 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=E2=80=99m 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:
 >=20
 > The attached patch addresses part of the problem.
 >=20
 > There are some other parts to address -- noted in the man page for the
 > new acpivmgenid(4) driver -- which I'll pick up later.
 =EF=BF=BC
 
 --Apple-Mail=_8F5D9F90-5683-49D7-B788-791C1D0129CA
 Content-Type: multipart/mixed;
 	boundary="Apple-Mail=_802E65D2-E476-4204-8205-1F07FBBF065A"
 
 
 --Apple-Mail=_802E65D2-E476-4204-8205-1F07FBBF065A
 Content-Transfer-Encoding: quoted-printable
 Content-Type: text/html;
 	charset=utf-8
 
 <html><head><meta http-equiv=3D"content-type" content=3D"text/html; =
 charset=3Dutf-8"></head><body style=3D"overflow-wrap: break-word; =
 -webkit-nbsp-mode: space; line-break: after-white-space;">Thank you for =
 the quick patch, awesome work!<div><br></div><div>One more thing: would =
 it make sense to mention this in the man page for arc4random and =
 getentropy? For context, I=E2=80=99m implementing random number =
 generation in the Rust standard library (see <a =
 href=3D"https://github.com/rust-lang/rust/pull/129201";>https://github.com/=
 rust-lang/rust/pull/129201</a>), and the library team would quite like =
 to make sure that the system sources we use protect against VM forks (<a =
 href=3D"https://github.com/rust-lang/rust/pull/129201#issuecomment-2302563=
 968">https://github.com/rust-lang/rust/pull/129201#issuecomment-2302563968=
 </a>), so having this as an explicit guarantee on NetBSD would ease some =
 concerns.<br id=3D"lineBreakAtBeginningOfMessage"><div><br><blockquote =
 type=3D"cite"><div>On 25. Aug 2024, at 22:52, Taylor R Campbell =
 &lt;riastradh%NetBSD.org@localhost&gt; wrote:</div><br =
 class=3D"Apple-interchange-newline"><div><div>The attached patch =
 addresses part of the problem.<br><br>There are some other parts to =
 address -- noted in the man page for the<br>new acpivmgenid(4) driver -- =
 which I'll pick up =
 later.<br></div></div></blockquote></div></div></body></html>=
 
 --Apple-Mail=_802E65D2-E476-4204-8205-1F07FBBF065A
 Content-Disposition: attachment;
 	filename=pr58632-vmgenid.patch
 Content-Type: text/plain;
 	x-unix-mode=0666;
 	name="pr58632-vmgenid.patch"
 Content-Transfer-Encoding: quoted-printable
 
 # 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+=3D	irframe.4 cir.4 irframetty.4 oboe.
  # ACPI devices
  MAN+=3D	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+=3D	apei.4
 =20
  # 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=3D260709
 +.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=3D260709
 + *
 + *	`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[] =3D {
 +	{ .compat =3D "VM_Gen_Counter" },		/* from the =
 Microsoft spec */
 +	{ .compat =3D "VM_GEN_COUNTER" },		/* used by qemu =
 */
 +	{ .compat =3D "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 =3D 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 =3D device_private(self);
 +	const struct acpi_attach_args *const aa =3D aux;
 +	ACPI_BUFFER addrbuf =3D {
 +		.Pointer =3D NULL,
 +		.Length =3D 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 =3D self;
 +	sc->sc_node =3D 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 =3D 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 =3D addrbuf.Pointer;
 +	if (addrobj->Type !=3D ACPI_TYPE_PACKAGE ||
 +	    addrobj->Package.Count !=3D 2) {
 +		aprint_error_dev(self, "invalid ADDR\n");
 +		goto out;
 +	}
 +	addrarr =3D addrobj->Package.Elements;
 +	if (addrarr[0].Type !=3D ACPI_TYPE_INTEGER ||
 +	    addrarr[1].Type !=3D 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 =3D =
 (ACPI_PHYSICAL_ADDRESS)addrarr[0].Integer.Value;
 +	sc->sc_paddr |=3D =
 (ACPI_PHYSICAL_ADDRESS)addrarr[1].Integer.Value << 32;
 +	aprint_normal_dev(self, "paddr=3D0x%"PRIx64"\n", =
 (uint64_t)sc->sc_paddr);
 +
 +	/*
 +	 * Map the physical address into virtual address space.
 +	 */
 +	sc->sc_vaddr =3D AcpiOsMapMemory(sc->sc_paddr, =
 sizeof(*sc->sc_vaddr));
 +	if (sc->sc_vaddr =3D=3D 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 =3D 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 =3D 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) =3D=3D sizeof(long));
 +	error =3D 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 =3D device_private(self);
 +	int error;
 +
 +	error =3D 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 =3D NULL;	/* paranoia */
 +	}
 +	sc->sc_paddr =3D 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 =3D 0; i < __arraycount(vmgenid.id); i++) {
 +		vmgenidstr[2*i] =3D "0123456789abcdef"[vmgenid.id[i] >> =
 4];
 +		vmgenidstr[2*i + 1] =3D "0123456789abcdef"[vmgenid.id[i] =
 & 0xf];
 +	}
 +	vmgenidstr[2*sizeof(vmgenid)] =3D '\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 =3D opaque;
 +	struct acpivmgenid_softc *const sc =3D device_private(self);
 +
 +	if (notify !=3D 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 =3D 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 =3D *rnode;
 +	struct acpivmgenid_softc *const sc =3D node.sysctl_data;
 +
 +	node.sysctl_data =3D 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 =3D 0;
 +
 +	switch (cmd) {
 +	case MODULE_CMD_INIT:
 +#ifdef _MODULE
 +		error =3D =
 config_init_component(cfdriver_ioconf_acpivmgenid,
 +		    cfattach_ioconf_acpivmgenid, =
 cfdata_ioconf_acpivmgenid);
 +#endif
 +		return error;
 +	case MODULE_CMD_FINI:
 +#ifdef _MODULE
 +		error =3D =
 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
 =20
 +# 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+=3D	acpilid
  SUBDIR+=3D	acpipmtr
  SUBDIR+=3D	acpitz
  SUBDIR+=3D	acpivga
 +SUBDIR+=3D	acpivmgenid
  SUBDIR+=3D	acpiwdrt
  SUBDIR+=3D	acpiwmi
  SUBDIR+=3D	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=3D	acpivmgenid
 +IOCONF=3D	acpivmgenid.ioconf
 +SRCS=3D	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?
 =20
  # 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
 
 --Apple-Mail=_802E65D2-E476-4204-8205-1F07FBBF065A
 Content-Transfer-Encoding: 7bit
 Content-Type: text/html;
 	charset=us-ascii
 
 <html><head><meta http-equiv="content-type" content="text/html; charset=us-ascii"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div><div><blockquote type="cite"><div><div></div></div></blockquote></div><br></div></body></html>
 --Apple-Mail=_802E65D2-E476-4204-8205-1F07FBBF065A--
 
 --Apple-Mail=_8F5D9F90-5683-49D7-B788-791C1D0129CA--
 



Home | Main Index | Thread Index | Old Index