hyperlight-dev / hyperlight-dev/hyperlight

Support Rdrand/rdseed instruction in hyperlight_guest

Open
#202 0 comments 0 reactions 0 assignees View on GitHub
area/security lifecycle/confirmed
Dominant language
Rust
Stars
4.7k
Forks
208
Avg merge
1d 7h
Merged PRs (30d)
47

Description

The use of rdrand in hyperlight_guest for random number generation has been removed due to issues where the Host OS has prevented its use causing a KVM exit with a Internal Error.

Some hosts can choose to not support the user of RDRAND and RDSEED instructions in guests. Intel VMX provides the capability to turn usage of these instructions to VM Exits by setting bits in the MSR IA32_VMX_PROCBASED_CTLS2 (see [here](https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3c-part-3-manual.pdf) for details).

Linux/KVM will process these exits as invalid operations (see [here](https://github.com/torvalds/linux/blob/a4145ce1e7bc247fd6f2846e8699473448717b37/arch/x86/kvm/vmx/vmx.c#L6143)).

The use of rdrand in WSL with Ubuntu/KVM (18.04/20.04/22.04) causes invalid operation errors as does a local non virtualised install of Ubuntu 22.04. It is not clear what causes Linux to disable support for rdrand in these scenarios, there is code in the kernel which checks to see if rdrand produces sufficiently random results and disables it in the host if not, this is not happening as if we check for support in the host it is enabled.

Regardless there are a couple of things that we can do:

In hyperlight_host we can ensure that rdrand is supported in the host and that it is allowed in the guest (by clearing the bit in IA32_VMX_PROCBASED_CTLS2 and ensuring that CPUID checks for RDRAND are successful). Brief attempts at setting this up in the KVM hypervisor module were not successful (failed to get/set the CPUID property and failed to get/set the MSR), but with more investigation this should be possible. It would need to be done in all hypervisor modules.

It may be that the issue seen with KVM was due to the way we were creating threads and using the KVM API in the past, we should re-test and see if this is still an issue

Alongside this the guest should be updated to test for rdrand support something like this:

```
let mut _eax: u32 = 1;
let _ebx: u32;
let mut ecx: u32;
let _edx: u32;

asm!(
"mov {0:r}, rbx",
"cpuid",
"xchg {0:r}, rbx",
out(reg) _ebx,
inout("eax") _eax,
out("ecx") ecx,
out("edx") _edx,
options(nostack, preserves_flags),
);

if ecx & (1 << 30) != 0 {
has_rdrand = true;
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.