A pool-operator can inject a controlled Python module name via Host.other_config:multipathhandle. The SM driver's SR._mpathinit() at SR.py:474-475 passes this value directly to Python's __import__() function as mpath_<value>. While an os.path.exists() check at line 469 verifies the file exists, this requires a file write primitive to place a .py file in /opt/xensource/sm/. Combined with BOC-1, a vm-admin can write mpath_evil.py to the SM driver directory and then set multipathhandle=evil to achieve arbitrary code execution as root during the next SR operation. Standalone, this requires pool-operator plus an independent file write capability.
Host.other_config is a Map(String, String) field writable by pool-operator. The multipathhandle key controls which multipath module the SM driver imports at runtime.
The code path:
pool-operator calls Host.add_to_other_config(host, "multipathhandle", "evil")SR._mpathinit() is calledSR.py:469 checks os.path.exists("/opt/xensource/sm/mpath_evil.py")SR.py:474-475 calls __import__("mpath_evil")The only valid values for multipathhandle are dmp and null, corresponding to mpath_dmp.py and mpath_null.py. No allowlist is enforced - any value that corresponds to an existing file in the SM directory is accepted.
With BOC-1, the attack becomes a two-step vm-admin-to-root chain:
mpath_evil.py to /opt/xensource/sm/multipathhandle=evilThis chain escalates from vm-admin to persistent root code execution.
Missing RBAC protection. Host.other_config has zero map_keys_roles entries for the multipathhandle key. Any pool-operator can modify it.
Unsafe dynamic import. __import__() with unsanitized user input is a known code execution primitive. The os.path.exists() check is not a security control - it verifies the file exists, not that it is authorized.
Missing allowlist. Only dmp and null are valid values, but no allowlist restricts the input.
| Scenario | Impact | Pre-conditions | Status |
|---|---|---|---|
| Module import injection (standalone) | Root code execution during SR operations | pool-operator + file write to /opt/xensource/sm/ |
Source-traced (High confidence) |
| BOC-1 + HOC-1 chain | vm-admin achieves persistent root code execution | BOC-1 available | Modeled (multi-step chain) |
Host.other_config for multipathhandle changesdmp or null/opt/xensource/sm/mpath_*.py for unexpected filesdisclosure/vendor-detection-guidance.mdHost.other_config for unexpected multipathhandle values/opt/xensource/sm/ for unexpected mpath_*.py filesReplace __import__() with explicit allowlist. Replace the dynamic import with conditional logic that only accepts dmp and null. Reject all other values.
Add map_keys_roles. Protect multipathhandle in datamodel.ml at _R_POOL_ADMIN.
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
vendor/sm/drivers/SR.py:469-475 (os.path.exists check + __import__ call), datamodel.ml (Host field definition)disclosure/advisories/hoc-security-advisory.md (HOC-1)research/investigations/host-other-config.mdDiscovered and reported by Jakob Wolffhechel, Moksha.