Re: [PATCH] drivers/virt: vmgenid: add vm generation id driver

From
Jann Horn via Virtualization <hidden>
Date
2020-10-17 05:39:45
Also in
kvm, linux-api, linux-doc, linux-s390, lkml, qemu-devel
On Sat, Oct 17, 2020 at 6:34 AM Colm MacCarthaigh [off-list ref] wrote:
On 16 Oct 2020, at 21:02, Jann Horn wrote:
quoted
On Sat, Oct 17, 2020 at 5:36 AM Willy Tarreau [off-list ref] wrote:
But in userspace, we just need a simple counter. There's no need for
us to worry about anything else, like timestamps or whatever. If we
repeatedly fork a paused VM, the forked VMs will see the same counter
value, but that's totally fine, because the only thing that matters to
userspace is that the counter changes when the VM is forked.
For user-space, even a single bit would do. We added MADVISE_WIPEONFORK
so that userspace libraries can detect fork()/clone() robustly, for the
same reasons. It just wipes a page as the indicator, which is
effectively a single-bit signal, and it works well. On the user-space
side of this, I’m keen to find a solution like that that we can use
fairly easily inside of portable libraries and applications. The “have
I forked” checks do end up in hot paths, so it’s nice if they can be
CPU cache friendly. Comparing a whole 128-bit value wouldn’t be my
favorite.
I'm pretty sure a single bit is not enough if you want to have a
single page, shared across the entire system, that stores the VM
forking state; you need a counter for that.
quoted
And actually, since the value is a cryptographically random 128-bit
value, I think that we should definitely use it to help reseed the
kernel's RNG, and keep it secret from userspace. That way, even if the
VM image is public, we can ensure that going forward, the kernel RNG
will return securely random data.
If the image is public, you need some extra new raw entropy from
somewhere. The gen-id could be mixed in, that can’t do any harm as
long as rigorous cryptographic mixing with the prior state is used, but
if that’s all you do then the final state is still deterministic and
non-secret.
Microsoft's documentation
(http://go.microsoft.com/fwlink/?LinkId=260709) says that the VM
Generation ID that we get after a fork "is a 128-bit,
cryptographically random integer value". If multiple people use the
same image, it guarantees that each use of the image gets its own,
fresh ID: The table in section "How to implement virtual machine
generation ID support in a virtualization platform" says that (among
other things) "Virtual machine is imported, copied, or cloned"
generates a new generation ID.

So the RNG state after mixing in the new VM Generation ID would
contain 128 bits of secret entropy not known to anyone else, including
people with access to the VM image.

Now, 128 bits of cryptographically random data aren't _optimal_; I
think something on the order of 256 bits would be nicer from a
theoretical standpoint. But in practice I think we'll be good with the
128 bits we're getting (since the number of users who fork a VM image
is probably not going to be so large that worst-case collision
probabilities matter).
The kernel would need to use the change as a trigger to
measure some entropy (e.g. interrupts and RDRAND, or whatever). Our just
define the machine contract as “this has to be unique random data and
if it’s not unique, or if it’s pubic, you’re toast”.
As far as I can tell from Microsoft's spec, that is a guarantee we're
already getting.
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization
Thread (1 message) 1 message, 1 author, last reply 2020-10-17
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help