MOKSHA-2026-0050: LUNperVDI Mode Manipulation via SR.sm_config

Advisory IDMOKSHA-2026-0050
Semantic IDSSMC-5
Published2026-04-24
CVSS 3.15.5 Medium
CVSS 3.1 VectorAV:N/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:H
CVSS 4.05.1 Medium
CVSS 4.0 VectorAV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
XAPI ObjectSR
XAPI Fieldsm_config:LUNperVDI
Entry Rolepool-operator
ResearcherJakob Wolffhechel, Moksha

Affected Products

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

Summary

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.

Vulnerability Description

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:

  1. During SR.create, the SM driver calls SR._addLUNperVDIkey() at SR.py:228
  2. _addLUNperVDIkey() sets sm_config["LUNperVDI"] = "true" via XAPI for SRs that use one-LUN-per-VDI mode
  3. The key persists in the database as part of SR.sm_config
  4. A pool-operator modifies the key:
    • Adds LUNperVDI=true to a shared-LUN SR: SR.add_to_sm_config(sr, "LUNperVDI", "true")
    • Or removes it from a LUN-per-VDI SR: SR.remove_from_sm_config(sr, "LUNperVDI")
  5. On the next SR operation, the driver reads sm_config and uses the wrong VDI management mode
  6. VDI creation uses wrong assumptions about LUN mapping
  7. VDI scanning returns incorrect results or fails
  8. VDI deletion targets wrong storage objects

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

Root Causes

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

  2. Missing RBAC protection. SR.sm_config has zero map_keys_roles entries. The LUNperVDI key inherits the class default _R_POOL_OP.

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

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

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

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

Chaining Analysis

Detection

Remediation

Short-Term Mitigations

Long-Term Fix

Enforce 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

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