A user with the vm-admin role - the lowest delegated management role in XAPI-based hypervisors (XenServer, XCP-ng) - can mount any host block device as a guest virtual disk by writing an arbitrary filesystem path to VBD.other_config:backend-local. The attack requires a single API call, no exploit code, no shell access, and produces no security alerts. The vulnerability collapses the entire XAPI RBAC hierarchy: a vm-admin gains root-equivalent access to the hypervisor host, can read any co-hosted VM's disk, exfiltrate credentials, inject SSH backdoors, and move laterally across shared storage - all from a single delegated admin credential.
VBD.other_config is a Map(String, String) field in the XAPI data model. The backend-local key overrides the normal storage path for a virtual block device. When a VBD is plugged (via VM start or hotplug), XAPI reads this key in xapi_xenops.ml:backend_of_vbd and passes the path directly to xenopsd with no validation, no access control check, and only a warn-level log message.
The code path:
vm-admin calls VBD.add_to_other_config(vbd, "backend-local", "/dev/sda1")xapi_xenops.ml:backend_of_vbd reads other_config["backend-local"]No validation occurs at any stage. The warn-level log message ("Using local override for VBD backend") is the only trace of the operation.
Missing RBAC protection. VBD.other_config has zero map_keys_roles entries in datamodel.ml. Every infrastructure-critical key, including backend-local, is writable by vm-admin via add_to_other_config.
Missing consumer-side validation. backend_of_vbd in xapi_xenops.ml consumes the backend-local key without any path validation, access control check, or security-level logging.
set_other_config RBAC bypass. The set_other_config method replaces the entire map atomically and bypasses map_keys_roles per-key checks entirely. This is a pre-existing architectural limitation shared by all XAPI objects.
Insufficient logging. The only indicator is a warn-level message. No security alert, no RBAC denial event, no anomaly detection trigger.
| Scenario | Impact | Status |
|---|---|---|
| S1: Cross-VM VDI exfiltration | Read any co-hosted VM's disk contents | Confirmed |
| S2: Host root filesystem read | Read /etc/shadow, XAPI state.db, SSH keys |
8/8 PASS |
| S3: RBAC hierarchy collapse | Self-grant pool-admin via on-disk database edit | 7/7 PASS (dom0), guest-side PoC ready |
| S4: SSH key injection backdoor | Persistent root SSH access surviving reboots | 8/8 PASS |
| S5: Shared storage lateral movement | Read VDIs across hosts via shared NFS/iSCSI | 9/9 PASS |
| Scenario | Impact | Status |
|---|---|---|
| S6: BOC-1 + SMC-1 chain | Silent storage protocol injection against storage arrays | Code-traced |
| S7: Cross-host local SR exfiltration | Read VDIs from remote host's local storage | PoC ready |
| S8: USB device exfiltration | Mount host USB storage as guest disk | PoC ready |
vm-admin credential (single API call)
|
v
S1: Read any VM's VDI on the same host
|
+---> S7: Read VDIs from remote host's local storage
|
v
S2: Read the host root filesystem
|
+---> S3: Self-grant pool-admin (permanent RBAC collapse)
+---> S4: SSH key injection (persistent root access)
+---> S5: Shared storage lateral movement (pool-wide compromise)
+---> S6: pool-admin + SMC-1 (silent storage array attacks)
+---> S8: USB device exfiltration
VBD.other_config entries for the backend-local key: any non-empty value is suspiciousdisclosure/vendor-detection-guidance.mdThere is no reliable post-compromise detection. The S3 RBAC collapse leaves no API audit trail because the role change is loaded from the tampered on-disk database at XAPI startup, not modified through the API. XAPI performs no integrity verification on state.db at load time.
vm-admin delegated access immediatelyVBD.other_config records for unexpected backend-local keysLayer 1 - RBAC (Patch 0001): Add map_keys_roles entries to VBD.other_config in datamodel.ml. The backend-local key requires _R_LOCAL_ROOT_ONLY (no API user can set it). The backend-kind key requires _R_POOL_ADMIN.
Layer 2 - Validation (Patch 0002): Add a config-driven validation gate in xapi_xenops.ml:backend_of_vbd. A new flag allow_vbd_backend_local (default: false) rejects the override when disabled. Defense-in-depth: blocks the attack even if RBAC is bypassed via set_other_config.
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
xapi_xenops.ml:backend_of_vbd, datamodel.ml (VBD field definition)disclosure/advisories/boc-1-security-advisory.mdresearch/investigations/vbd-other-config.mdresearch/boc-1/poc/ (available to CSIRTs on request)Discovered and reported by Jakob Wolffhechel, Moksha.