A vm-admin in XAPI-based hypervisors (XenServer, XCP-ng) can disable CPU security features and modify hypervisor behavior for a VM by writing to security-critical keys in VM.platform. Setting nx=false disables the No-Execute bit (removing DEP protection), setting hap=false forces shadow paging mode (different security properties and performance degradation), setting nested-virt=true enables nested virtualization (expanding the attack surface), and setting extreme values for max_grant_frames or max_maptrack_frames causes resource exhaustion. The VM.platform field has zero map_keys_roles entries - all keys are writable by vm-admin, the lowest delegated management role.
VM.platform is a Map(String, String) field defined at datamodel_vm.ml:2717-2720 with no ~map_keys_roles parameter. Multiple keys directly control hypervisor security features:
Read at domain creation by xenopsd. Setting nx=false removes the NX/XD bit from the guest's CPU feature set, disabling Data Execution Prevention. The guest becomes vulnerable to code execution attacks that exploit writable+executable memory regions.
Read at domain.ml:325 by xenopsd. Setting hap=false forces the VM to use shadow paging instead of hardware-assisted paging (EPT/NPT). Shadow paging has different security properties, introduces performance overhead, and activates a larger code surface in the hypervisor's shadow paging implementation.
Read at xenops_server_xen.ml:1396-1399. Setting nested-virt=true enables nested virtualization, expanding the attack surface by exposing the nested VMX/SVM instruction set to the guest. The guest can create sub-VMs, which interact with a more complex hypervisor code path. A pool feature flag (Features.Nested_virt) provides an additional gate for this key, but nx and hap have no such gate.
Read at domain.ml:378-383. Setting extreme values causes oversized grant table or maptrack frame allocation during domain creation. The parser uses int_of_string with a catch-all defaulting to 64 (grant) or 1024 (maptrack), but valid-but-extreme values (e.g., 999999) pass the parser and cause resource exhaustion.
All of these keys are validated only at VM start time (if at all). There is no write-time validation. A vm-admin can set any value at any time, and the malicious value persists in the database until the next VM start.
Missing RBAC protection. VM.platform has zero map_keys_roles entries. Security-critical hypervisor keys (nx, hap, nested-virt, max_grant_frames, max_maptrack_frames) are writable by the lowest delegated management role.
No write-time validation. Security feature keys are not validated when they are written. The value persists in the database and takes effect at the next VM start.
Inconsistent feature gating. nested-virt has an additional pool feature flag gate. nx, hap, max_grant_frames, and max_maptrack_frames have no such gate - they are consumed directly at domain creation.
Privilege-impact mismatch. Disabling CPU security features and modifying hypervisor paging mode are infrastructure-level security decisions. These should require pool-admin or higher, not vm-admin.
| Scenario | Impact | Pre-conditions | Status |
|---|---|---|---|
| NX bit removal | Guest loses DEP protection, vulnerable to code execution attacks | vm-admin, VM restart | Source-traced |
| Shadow paging forced | Guest moved to shadow paging mode, performance degradation, different security surface | vm-admin, VM restart | Source-traced |
| Nested virtualization enabled | Expanded hypervisor attack surface, guest can create sub-VMs | vm-admin, pool feature flag enabled, VM restart | Source-traced |
| Grant table exhaustion | Extreme max_grant_frames causes resource exhaustion during domain creation | vm-admin, VM restart | Source-traced |
| BOC-1 chain | Pool-wide security feature disablement via root access | vm-admin, BOC-1 | Source-traced |
VM.platform writes for keys: nx, hap, nested-virt, max_grant_frames, max_maptrack_framesnx=false or hap=false settings, which reduce security posturemax_grant_frames (> 256) or max_maptrack_frames (> 4096)disclosure/vendor-detection-guidance.mdVM.platform records for security-critical key modificationsnx=false, hap=false, or unusual nested-virt settingsmax_grant_frames/max_maptrack_frames valuesAdd map_keys_roles to VM.platform. Restrict security-critical keys (nx, hap, nested-virt, max_grant_frames, max_maptrack_frames) to _R_POOL_ADMIN.
Add write-time validation. Validate security feature keys when they are set, not only at VM start. Reject nx=false and hap=false unless the caller has pool-admin privileges.
Add range validation. Enforce reasonable bounds on max_grant_frames and max_maptrack_frames at write time.
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
datamodel_vm.ml:2717-2720 (field definition, no map_keys_roles), domain.ml:325 (hap key consumed at domain creation), domain.ml:378-383 (max_grant_frames/max_maptrack_frames), xenops_server_xen.ml:1396-1399 (nested-virt key), vm_platform.ml:1-271 (sanity_check at start time, not write time)disclosure/advisories/plat-security-advisory.md (PLAT-5)research/investigations/vm-platform.mdDiscovered and reported by Jakob Wolffhechel, Moksha.