MOKSHA-2026-0008: Storage Driver Domain PBD Detach DoS via VM.other_config

Advisory IDMOKSHA-2026-0008
Semantic IDVOC-2
Published2026-04-24
CVSS 3.18.2 High
CVSS 3.1 VectorAV:N/AC:L/PR:L/UI:N/S:C/C:N/I:L/A:H
CVSS 4.08.4 High
CVSS 4.0 VectorAV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:H/SC:N/SI:L/SA:H
XAPI ObjectVM
XAPI Fieldother_config:storage_driver_domain
Entry Rolevm-admin
ResearcherJakob Wolffhechel, Moksha

Affected Products

VendorProductVersions
Citrix / Cloud Software GroupXenServer / Citrix Hypervisorall versions (shared XAPI codebase)
VatesXCP-ng8.3.0

Summary

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.

Vulnerability Description

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.

Code Paths

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.

Attack Mechanism

  1. vm-admin calls VM.add_to_other_config(vm, "storage_driver_domain", "<pbd_ref>")
  2. The PBD reference can point to any PBD in the pool
  3. On VM shutdown: Storage_access.reset clears XAPI's storage state for the targeted SR
  4. On VM start: Xapi_pbd.plug forces a PBD reconnection

The 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.

State Race Absorption

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.

Root Causes

  1. 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.

  2. 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.

  3. 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.

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

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)

Detection

Remediation

Short-Term Mitigations

Long-Term Fix

RBAC: 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

Disclosure:

References

Credits

Discovered and reported by Jakob Wolffhechel, Moksha.

Jakob Wolffhechel · Moksha · Copenhagen
jakob@wolffhechel.dk · +45 3170 7337
Published 2026-04-24 08:00 CEST · cna.moksha.dk · shittrix.moksha.dk