MOKSHA-2026-0036: LVM Configuration Injection via SR.other_config lvm-conf

Advisory IDMOKSHA-2026-0036
Semantic IDSOC-2
Published2026-04-24
CVSS 3.16.7 Medium
CVSS 3.1 VectorAV:N/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H
CVSS 4.07.0 High
CVSS 4.0 VectorAV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:H/VA:L/SC:N/SI:L/SA:N
XAPI ObjectSR
XAPI Fieldother_config:lvm-conf
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 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.

Vulnerability Description

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:

  1. pool-operator calls SR.add_to_other_config(sr, "lvm-conf", "filter=[\"a|.*|\"]")
  2. LVHDSR.__init__() reads self.lvm_conf = self.other_conf.get('lvm-conf') (LVHDSR.py:177)
  3. LVM utility functions interpolate the value: cmd.extend(["--config", "devices{" + config_param + "}"]) (lvutil.py:626-630)
  4. The extended command is executed via pread2 (list-based, no shell)
  5. LVM applies the injected configuration override for the duration of the command

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.

Root Causes

  1. Missing RBAC protection. SR.other_config has no map_keys_roles entry for lvm-conf. The key inherits the class default _R_POOL_OP.

  2. Unsanitized configuration injection. The value flows from the XAPI database directly into LVM command arguments. No validation against an allowlist or grammar.

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

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

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

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

Detection

Remediation

Short-Term Mitigations

Long-Term Fix

Remove 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

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