A vm-admin can inject an arbitrary mem-pool value into VDI.other_config that flows unsanitized to tapdisk - a root-level storage I/O daemon - via xenstore. The SM driver reads other_config["mem-pool"] in blktap2.py:1548-1550 without any sanitization and writes it to xenstore as a tapdisk parameter at blktap2.py:1565,1579. Tapdisk runs as root and reads the unsanitized pool name from xenstore to configure its memory allocation behavior. This creates a direct injection path from a low-privilege API user into a root-level service's configuration.
VDI.other_config is a Map(String, String) field writable by vm-admin. The mem-pool key controls which memory pool tapdisk uses for the VDI's I/O buffers. The value is read from the XAPI database by the SM driver and written to xenstore without sanitization.
vm-admin calls VDI.add_to_other_config(vdi, "mem-pool", "<arbitrary-value>")
-> blktap2.py:1548-1550 reads other_config["mem-pool"]
-> pool_name_override = vdi_config.get(POOL_NAME_KEY) # "mem-pool"
-> No sanitization, no format check, no allowlist
-> blktap2.py:1565 writes to xenstore: <tapdisk-path>/mem-pool = <arbitrary-value>
-> tapdisk (running as root) reads the xenstore key
-> Uses the value to configure memory pool allocation
# blktap2.py:1546-1567
vdi_config = self._session.xenapi.VDI.get_other_config(vdi_ref)
pool_name_override = vdi_config.get(POOL_NAME_KEY) # "mem-pool"
if pool_name_override:
# No sanitization - value written directly to xenstore
...
Tapdisk is the userspace block device daemon that handles VDI I/O in XAPI-based hypervisors. It runs as root in dom0. The mem-pool xenstore key controls how tapdisk allocates memory for I/O buffers associated with a VDI. An attacker-controlled value in this key reaches a root service's configuration path.
A related key, mem-pool-size-rings, has partial validation: blktap2.py:1551-1563 enforces a range of 1-8 for this value. However, mem-pool (the pool name itself) has zero validation.
Missing RBAC protection. VDI.other_config has zero map_keys_roles entries for infrastructure keys. The mem-pool key is writable by vm-admin.
Zero sanitization. The SM driver reads the value and writes it to xenstore without any sanitization, format check, or allowlist.
Privilege boundary violation. A vm-admin user (lowest management role) can inject values that reach a root-level service's configuration via xenstore.
Inconsistent validation. mem-pool-size-rings has range validation (1-8), but mem-pool has none - inconsistent handling of related configuration keys.
| Scenario | Impact | Pre-conditions | Status |
|---|---|---|---|
| Memory pool name injection | Arbitrary value reaches tapdisk config via xenstore | VDI with tapdisk backend | Confirmed (injection path code-traced end-to-end) |
| Tapdisk memory behavior manipulation | Altered memory allocation for VDI I/O | Tapdisk reads the injected pool name | Modeled (depends on tapdisk's pool name handling) |
| Cross-VDI memory pool collision | Force VDIs to share memory pools, causing resource contention | Multiple VDIs on same host | Modeled |
VDI.other_config writes for the mem-pool keymem-pool valuesmem-pool values containing non-alphanumeric charactersdisclosure/vendor-detection-guidance.mdVDI.other_config records for unexpected mem-pool valuesInput sanitization. In blktap2.py, whitelist alphanumeric characters for mem-pool and enforce a maximum length before writing to xenstore.
Add map_keys_roles. Protect mem-pool in datamodel.ml at _R_POOL_ADMIN to prevent vm-admin from setting it.
Xenstore write validation. Implement a validation layer between SM driver reads and xenstore writes for all tapdisk parameters.
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
blktap2.py:1548-1550 (mem-pool read from other_config), blktap2.py:1565,1579 (xenstore write), datamodel.ml (VDI field definition)disclosure/advisories/doc-security-advisory.md (DOC-1)research/investigations/vdi-other-config.mdDiscovered and reported by Jakob Wolffhechel, Moksha.