A pool-operator in XAPI-based hypervisors (XenServer, XCP-ng) can manipulate the filesystem layout of NFS and MooseFS storage repositories by modifying the nosubdir or subdir key in SR.sm_config after SR creation. Changing nosubdir from false to true (or vice versa) on an NFS SR causes the driver to look for VDIs in the wrong directory. All VDIs appear to not exist, causing VM boot failures and complete data inaccessibility. The attack is reversible by restoring the correct value but causes service disruption for all VMs on the affected SR. The sm_config field has zero map_keys_roles entries, and these keys are intended to be set once during SR.create but remain writable.
SR.sm_config is a Map(String, String) field writable by pool-operator. The nosubdir key (NFS) and subdir key (MooseFS) control whether the SR driver stores VDIs in a per-SR subdirectory on the remote filesystem or in the root of the shared export.
The code path:
SR.create, the SM driver sets sm_config:nosubdir based on the creation parametersNFSSR.__init__() reads self.nosubdir = self.sm_config.get('nosubdir') == "true" (NFSSR.py:95)not self.nosubdir and sr_uuid or "" (NFSSR.py:100)pool-operator changes nosubdir from "false" to "true" (or vice versa)For NFS SRs:
nosubdir=false (default): VDIs stored at <mountpoint>/<sr-uuid>/nosubdir=true: VDIs stored at <mountpoint>/Flipping this flag causes the driver to look for VDIs in the wrong directory. The VDI files still exist on disk but are invisible to the driver.
The same pattern applies to MooseFS SRs via the subdir key (MooseFSSR.py).
Missing field immutability. SR.sm_config is qualifier:RW despite containing keys that define the SR's physical layout and should be immutable after creation.
Missing RBAC protection. SR.sm_config has zero map_keys_roles entries. The nosubdir and subdir keys inherit the class default _R_POOL_OP.
No consistency check. The driver does not verify that VDI files exist at the computed path before reporting them as missing. A simple existence check at the alternate location would detect the misconfiguration.
Mutable layout metadata. The physical layout of an SR (subdirectory vs. root) is a creation-time decision. Storing it in a mutable field allows post-creation corruption.
| Scenario | Impact | Pre-conditions | Status |
|---|---|---|---|
| NFS layout flip | All VDIs on NFS SR appear missing, VM boot failures | pool-operator, NFS SR | Source-traced |
| MooseFS layout flip | All VDIs on MooseFS SR appear missing | pool-operator, MooseFS SR | Source-traced |
| Service disruption | All VMs on affected SR fail to boot or experience I/O errors | pool-operator, NFS/MooseFS SR with running VMs | Modeled |
| BOC-1 chain | vm-admin uses BOC-1 S3 to self-grant pool-operator, then flips layout flag | vm-admin, BOC-1 + NFS SR | Source-traced |
SR.sm_config for modifications to nosubdir or subdir keys after SR creationSR.sm_config snapshots between monitoring intervals for driftdisclosure/vendor-detection-guidance.mdSR.sm_config records on NFS/MooseFS SRs: verify nosubdir/subdir matches the actual filesystem layoutSR.sm_config to detect unauthorized changesEnforce sm_config immutability. Driver-set keys like nosubdir and subdir should be immutable after SR.create. Implement a write-once mechanism for layout-defining keys.
Add map_keys_roles. Protect nosubdir and subdir at _R_LOCAL_ROOT_ONLY in datamodel.ml.
Add consistency verification. When a VDI scan finds no VDIs at the expected path, check the alternate path (with/without subdirectory) and log a warning if VDIs exist at the alternate location.
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
datamodel.ml:4949-4953 (SR.sm_config field definition), NFSSR.py:95 (nosubdir read), NFSSR.py:100 (path construction using nosubdir flag)disclosure/advisories/ssmc-security-advisory.md (SSMC-4)research/investigations/sr-sm-config.mdDiscovered and reported by Jakob Wolffhechel, Moksha.