lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <YoZB/+EYDDfowVbs@czspare1-lap.sysgo.cz>
Date:   Thu, 19 May 2022 15:11:27 +0200
From:   Vit Kabele <vit.kabele@...go.com>
To:     linux-hyperv@...r.kernel.org
Cc:     linux-kernel@...r.kernel.org, decui@...rosoft.com,
        kys@...rosoft.com, rudolf.marek@...go.com, vit@...ele.me,
        wei.liu@...nel.org
Subject: Hyper-V: Question about initializing hypercall interface

Hello,

I'm playing with the Hyper-V interface described in the documentation
here [1] (version 6.0b) and I noticed inconsistency between the
document and the actual code in arch/x86/hyperv/hv_init.c.

Section 3.13 Establishing the Hypercall Interface states:

> 5. The guest checks the Enable Hypercall Page bit. If it is set, the
> interface is already active, and steps 6 and 7 should be omitted. 
> 6.  The guest finds a page within its GPA space, preferably one that
> is not occupied by RAM, MMIO, and so on. If the page is occupied, the
> guest should avoid using the underlying page for other purposes. 
> 7.  The guest writes a new value to the Hypercall MSR
> (HV_X64_MSR_HYPERCALL) that includes the GPA from step 6 and sets the
> Enable Hypercall Page bit to enable the interface.

Yet the code in hv_init.c seems to skip the step 5. and performs the
steps 6. and 7. unconditionally. Snippet below.

```
rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
hypercall_msr.enable = 1;

if (hv_root_partition) {
	...
} else {
    hypercall_msr.guest_physical_address = vmalloc_to_pfn(hv_hypercall_pg);
    wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
}
```

1/ I thought that the specification is written in a way that allows
hypervisor to locate the hypercall page on its own (for whatever reason)
and just announce the location to the guest by setting the Enable bit in
the MSR on initial read. A guest should then not attempt to remap the
page (point 5. above), but instead create kernel mapping to the page
reported by the hypervisor.

2/ The Lock bit (bit 1) is ignored in the Linux implementation. If the
hypervisor starts with Lock bit set, the init function allocates the
hv_hypercall_pg and writes the value to the MSR, then:
	a/ If the hypervisor ignores the write, the MSR remains unchanged,
		but the global variable is already set. Attempt to do a
		hypercall ends with call to undefined memory, because the code
		in hv_do_hypercall() checks the global variable against NULL,
		which will pass.
	b/ The hypervisor injects #GP, in which case the guest crashes.

Do I understand the specification correctly? If yes, then the issues
here are real issues. If my understanding is wrong, what do I miss?

-- 
Best regards,
Vit Kabele

[1]: https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ