A pool-operator in XAPI-based hypervisors (XenServer, XCP-ng) can inject arbitrary LVM configuration by setting SR.other_config:lvm-conf to a crafted value. The value is interpolated into --config devices{VALUE} in LVM commands executed by SM drivers (lvutil._remove(), lvutil.setActiveVG()) without sanitization. While pread2 (list-based process execution) prevents shell injection, the LVM --config parameter accepts arbitrary configuration overrides including devices { filter }, enabling device filter manipulation that affects which block devices LVM operates on. An attacker can alter device filter rules to include shared storage LUNs, bypass LVM safety restrictions, or cause cross-SR device operations.
SR.other_config is a Map(String, String) field writable by pool-operator. The lvm-conf key is consumed by SM drivers at multiple points in the LVM command chain.
The code path:
pool-operator calls SR.add_to_other_config(sr, "lvm-conf", "filter=[\"a|.*|\"]")LVHDSR.__init__() reads self.lvm_conf = self.other_conf.get('lvm-conf') (LVHDSR.py:177)cmd.extend(["--config", "devices{" + config_param + "}"]) (lvutil.py:626-630)pread2 (list-based, no shell)The lvm-conf value is not validated against any grammar. It accepts arbitrary LVM configuration syntax including device filter rules, metadata settings, and allocation policies.
Missing RBAC protection. SR.other_config has no map_keys_roles entry for lvm-conf. The key inherits the class default _R_POOL_OP.
Unsanitized configuration injection. The value flows from the XAPI database directly into LVM command arguments. No validation against an allowlist or grammar.
Overly permissive LVM --config. The LVM --config parameter is designed to override any configuration directive. Passing user-controlled data to this parameter gives the user full control over LVM behavior.
No audit trail. LVM configuration overrides via --config do not appear in persistent LVM configuration files. The injection is transient and invisible to post-hoc auditing.
| Scenario | Impact | Pre-conditions | Status |
|---|---|---|---|
| Device filter manipulation | LVM operates on unintended block devices, including shared storage LUNs from other SRs | pool-operator, LVM-backed SR | Source-traced |
| LVM safety restriction bypass | Attacker overrides safety settings that prevent destructive operations | pool-operator, LVM-backed SR | Source-traced |
| Cross-SR device operations | LVM commands target devices belonging to other storage repositories | pool-operator, multiple LVM SRs on same host | Modeled |
| BOC-1 chain | vm-admin uses BOC-1 S3 to self-grant pool-operator, then injects LVM config | vm-admin, BOC-1 + LVM SR | Source-traced |
SR.other_config for lvm-conf key writes--config overrideslvm-conf value in production SR configurationsdisclosure/vendor-detection-guidance.mdSR.other_config records for lvm-conf keyslvm-conf values from production SRs--config argumentsRemove or restrict lvm-conf. LVM configuration should not be user-writable. Either remove the key entirely or restrict it to a strict allowlist of known-safe configuration directives.
Add map_keys_roles. Protect lvm-conf at _R_POOL_ADMIN or _R_LOCAL_ROOT_ONLY in datamodel.ml.
Validate configuration syntax. If the key must remain, validate the value against a strict grammar that only permits the intended configuration directives (e.g., device filter patterns matching the SR's own devices).
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
datamodel.ml:4930-4935 (SR.other_config field definition), LVHDSR.py:177 (lvm-conf read), lvutil.py:626-630 (config interpolation into LVM commands)disclosure/advisories/soc-security-advisory.md (SOC-2)research/investigations/sr-other-config.mdDiscovered and reported by Jakob Wolffhechel, Moksha.