A user with the vm-admin role can inject a PBD reference into VM.other_config:storage_driver_domain on any VM. This key is the reverse link from a VM to its associated PBD, used by XAPI to manage storage driver domain lifecycle. When the injected VM is shut down, xapi_xenops.ml:2168-2170 calls Storage_access.reset on the referenced PBD's SR and then sets the PBD's currently_attached field to false - a denial-of-service that clears XAPI's internal storage state for the targeted SR. When the VM starts, xapi_xenops.ml:2198-2211 spawns a thread to Xapi_pbd.plug the injected PBD. Combined with VOC-1 (MOKSHA-2026-0003), the attacker gains both system domain privileges and PBD manipulation.
VM.other_config is a Map(String, String) field writable by vm-admin. The storage_driver_domain key stores a PBD reference that XAPI uses to manage the VM's relationship with storage infrastructure.
Read path - VM shutdown (xapi_xenops.ml:2168-2170):
let pbd_of_vm ~__context ~vm =
let other_config = Db.VM.get_other_config ~__context ~self:vm in
if List.mem_assoc storage_driver_domain_key other_config then
Some (Ref.of_string (List.assoc storage_driver_domain_key other_config))
else
None
When pbd_of_vm returns Some pbd, the shutdown path calls Storage_access.reset on the PBD's associated SR, then sets Db.PBD.set_currently_attached ~value:false.
Read path - VM start (xapi_xenops.ml:2198-2211):
On VM start, XAPI spawns a thread to call Xapi_pbd.plug on the injected PBD reference, forcing a PBD plug operation.
vm-admin calls VM.add_to_other_config(vm, "storage_driver_domain", "<pbd_ref>")Storage_access.reset clears XAPI's storage state for the targeted SRXapi_pbd.plug forces a PBD reconnectionThe PBD reference is read via Ref.of_string() with no validation that the reference is valid, belongs to the correct host, or refers to a PBD associated with this VM.
Backend verification found that the PBD detach is partially absorbed by a state race (ARCH-4) in current XCP-ng versions - the currently_attached field may be reset by concurrent operations. However, the Storage_access.reset call still clears XAPI's internal storage multiplexer state, which can cause transient storage disruptions.
Missing per-key RBAC. VM.other_config has no map_keys_roles entry for storage_driver_domain. The key is writable by vm-admin without restriction.
No validation on PBD reference. Ref.of_string() accepts any string as a PBD reference. No check verifies that the reference is valid, belongs to the correct host, or corresponds to a real PBD.
Infrastructure state in user-writable field. The VM-to-PBD reverse link is stored in a user-writable map field. This state should be managed internally by XAPI.
Storage_access.reset clears XAPI's internal state for the SR, potentially disrupting all VMs using that SR| Scenario | Impact | Pre-conditions | Status |
|---|---|---|---|
| PBD detach DoS | Clear XAPI storage state for targeted SR on VM shutdown | Target PBD reference known | Injection 9/9 PASS; PBD detach partially absorbed by ARCH-4 state race |
| PBD plug forcing | Force PBD reconnection on VM start, causing storage disruption | Same as above | Injection confirmed (source trace + live test) |
| VOC-2 + VOC-1 chain | System domain status + PBD manipulation = elevated storage DoS | Both VOC-1 and VOC-2 set on same VM | Write confirmed |
| Repeated cycling | Repeatedly start/stop the injected VM to cycle PBD state | Attacker controls VM lifecycle | Modeled (follows from basic attack) |
VM.other_config:storage_driver_domain writes by non-pool-admin sessionsstorage_driver_domain set on non-infrastructure VMs (in normal operation, only XAPI-created storage driver domain VMs have this key)Storage_access.reset calls correlated with VM shutdown eventsVM.other_config entries for unexpected storage_driver_domain valuesvm-admin role grants to trusted personnelRBAC: Add map_keys_roles entry for storage_driver_domain requiring _R_LOCAL_ROOT_ONLY in datamodel_vm.ml.
Validation: Validate the PBD reference at write time - verify it references an existing PBD on the correct host. Reject invalid references.
Architecture: Move storage_driver_domain out of other_config into a protected internal-only field managed exclusively by XAPI internal code.
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
system_domains.ml:91-96 (pbd_of_vm), xapi_xenops.ml:2168-2170 (VM shutdown PBD reset), xapi_xenops.ml:2198-2211 (VM start PBD plug), datamodel_vm.ml:2728-2737 (field definition)disclosure/advisories/voc-security-advisory.mdresearch/investigations/vm-other-config.md (VOC-2 section)research/voc-2/poc/voc-2-storage-driver-domain.py (available to CSIRTs on request)Discovered and reported by Jakob Wolffhechel, Moksha.