A pool-operator in XAPI-based hypervisors (XenServer, XCP-ng) can corrupt the VDI management mode of an SR by adding or removing the LUNperVDI key in SR.sm_config. The LUNperVDI key, defined at SR.py:37 and set by SR._addLUNperVDIkey() at SR.py:228, controls whether the SR maps one LUN per VDI or uses a shared LUN with VHD containers. Adding LUNperVDI=true to a non-LUN-per-VDI SR or removing it from a LUN-per-VDI SR causes VDI management mode mismatch, leading to VDI creation, deletion, and scanning failures. The SR.sm_config field has zero map_keys_roles entries and remains writable after SR creation.
SR.sm_config is a Map(String, String) field writable by pool-operator. The LUNperVDI key controls a fundamental aspect of the SR's storage architecture - whether each VDI corresponds to a separate LUN or whether multiple VDIs share a single LUN in VHD format.
The code path:
SR.create, the SM driver calls SR._addLUNperVDIkey() at SR.py:228_addLUNperVDIkey() sets sm_config["LUNperVDI"] = "true" via XAPI for SRs that use one-LUN-per-VDI modeSR.sm_configpool-operator modifies the key:LUNperVDI=true to a shared-LUN SR: SR.add_to_sm_config(sr, "LUNperVDI", "true")SR.remove_from_sm_config(sr, "LUNperVDI")sm_config and uses the wrong VDI management modeThe xe CLI rejects sm_config writes with "Map field 'sm-config' is read-only", but direct XenAPI calls (SR.add_to_sm_config, SR.remove_from_sm_config) succeed. The CLI provides a false sense of immutability.
Missing field immutability. SR.sm_config is qualifier:RW despite containing keys that define the SR's storage architecture. The LUNperVDI key is set during SR.create and should be immutable afterward.
Missing RBAC protection. SR.sm_config has zero map_keys_roles entries. The LUNperVDI key inherits the class default _R_POOL_OP.
CLI/API inconsistency. The xe CLI rejects sm_config writes, but the XenAPI accepts them. This creates a false sense of immutability for operators who only use the CLI.
No consistency check. The driver does not verify that the LUNperVDI mode matches the actual storage layout. A mismatch between the key and the physical storage structure causes operational failures.
| Scenario | Impact | Pre-conditions | Status |
|---|---|---|---|
| Mode injection (non-LUNperVDI SR) | Adding LUNperVDI=true to shared-LUN SR causes VDI creation/scan failures | pool-operator, shared-LUN SR | Source-traced |
| Mode removal (LUNperVDI SR) | Removing LUNperVDI from LUN-per-VDI SR causes wrong VDI management assumptions | pool-operator, LUNperVDI SR | Source-traced |
| VDI operation failures | VDI create, delete, scan operations use wrong storage layout assumptions | pool-operator | Source-traced |
| BOC-1 chain | vm-admin uses BOC-1 S3 to self-grant pool-operator, then corrupts LUNperVDI mode | vm-admin, BOC-1 | Source-traced |
LUNperVDI key to corrupt VDI management mode on HBA SRs.SR.sm_config for modifications to the LUNperVDI key after SR creationLUNperVDI key changes on any active SRSR.sm_config snapshots between monitoring intervals for driftdisclosure/vendor-detection-guidance.mdSR.sm_config records for unexpected LUNperVDI valuesLUNperVDI key matches the actual storage architecture on each SRsm_config changesEnforce sm_config immutability. Driver-set keys like LUNperVDI should be immutable after SR.create. Implement a write-once mechanism for architecture-defining keys.
Add map_keys_roles. Protect LUNperVDI at _R_LOCAL_ROOT_ONLY in datamodel.ml.
Add consistency verification. When reading LUNperVDI, verify that the storage layout matches the expected mode. Log a warning if a mismatch is detected.
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
datamodel.ml:4949-4953 (SR.sm_config field definition), SR.py:37 (LUNPERVDI constant), SR.py:228 (_addLUNperVDIkey writes the key)disclosure/advisories/ssmc-security-advisory.md (SSMC-5)research/investigations/sr-sm-config.mdDiscovered and reported by Jakob Wolffhechel, Moksha.