A vm-admin in XAPI-based hypervisors (XenServer, XCP-ng) can set VIF.qos_algorithm_params:kbps, which xenopsd writes as a raw Int64.to_string value to the VIF's private xenstore path at device.ml:920-927. The raw kbps and timeslice_us values are stored at /xapi/<domid>/private/vif/<devid>/rate and .../timeslice for xenopsd internal bookkeeping (VIF replug scenarios). While Int64.to_string prevents xenstore path injection (it produces only decimal digit characters), the raw user-controlled values are readable by dom0 processes that consume VIF private xenstore data. The VIF.qos_algorithm_params field has zero map_keys_roles entries.
VIF.qos_algorithm_params is a Map(String, String) field defined at datamodel.ml:1666-1681 via the qos function with zero map_keys_roles entries.
xenopsd writes raw rate values to two xenstore locations:
Backend path (device.ml:851) - computed bytes_per_interval:
rate = sprintf "%Lu,%Lu" bytes_per_interval timeslice_us
Written to: /local/domain/0/backend/vif/<domid>/<devid>/rate
Private data path (device.ml:920-927) - raw user-controlled values:
match rate with
| None -> []
| Some (rate, timeslice) ->
[ ("rate", Int64.to_string rate)
; ("timeslice", Int64.to_string timeslice) ]
Written to: /xapi/<domid>/private/vif/<devid>/rate and .../timeslice
The private path stores the raw kbps and timeslice_us values from the user, not the computed bytes_per_interval. These are formatted via Int64.to_string, which produces only decimal digit characters (optionally with a leading - for negative values).
The private xenstore path is readable only by dom0 processes. There is no guest-side visibility. Int64.to_string formatting prevents xenstore path separator injection or other injection attacks through this path.
The concern is the architectural pattern: user-controlled values from a vm-admin are stored in a dom0-readable location without any indication that they are attacker-supplied rather than system-generated.
Raw value passthrough. xenopsd stores the raw user-provided kbps and timeslice_us in private xenstore without marking them as user-supplied or validating them.
Missing RBAC protection. VIF.qos_algorithm_params has zero map_keys_roles entries. All keys are writable by vm-admin.
No provenance tracking. Dom0 processes that read the private xenstore path cannot distinguish between values set by XAPI internally and values injected by a vm-admin.
set_qos_algorithm_params RBAC bypass. The set_qos_algorithm_params method replaces the entire map and bypasses map_keys_roles per-key checks.
| Scenario | Impact | Pre-conditions | Status |
|---|---|---|---|
| Raw value in private xenstore | Attacker-controlled kbps value readable by dom0 processes | vm-admin, VIF with ratelimit QoS | Live-tested |
| Replug with stored value | xenopsd re-reads raw kbps from private xenstore on replug | vm-admin, VIF replug | Source-traced |
| Negative kbps in xenstore | Negative Int64 value stored as "-N" string in xenstore | vm-admin | Source-traced |
Int64.to_string formatting prevents injection through this path. The finding is informational - it documents the presence of attacker-controlled values in a dom0-readable location.rate values against XAPI DB kbps values for consistencydisclosure/vendor-detection-guidance.mdValidate before storing. Apply the same range validation to the private xenstore write path as the backend xenstore path. Do not store raw user-controlled values that failed validation.
Add provenance markers. Mark private xenstore values as validated or unvalidated so downstream consumers can distinguish system-generated from user-supplied data.
Add write-time validation for kbps. Reject invalid kbps values at the XAPI API boundary before they propagate to xenopsd and xenstore.
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
datamodel.ml:1666-1681 (VIF.qos_algorithm_params field definition), xapi_xenops.ml:781-808 (rate parsing), device.ml:920-927 (raw kbps/timeslice written to private xenstore via Int64.to_string)disclosure/advisories/vqp-security-advisory.md (VQP-5)research/investigations/vif-qos-algorithm-params.mdDiscovered and reported by Jakob Wolffhechel, Moksha.