A vm-admin in XAPI-based hypervisors (XenServer, XCP-ng) can inject negative kbps values into VIF.qos_algorithm_params. XAPI parses the value via Int64.of_string at xapi_xenops.ml:795 without any sign check or range validation. When the VIF is plugged, xenopsd computes a negative bytes_per_interval, which fails the bounds check at device.ml:850 (bytes_per_interval > 0L), causing the rate limit to be silently dropped. The XAPI database shows kbps=-1 (or any negative value) as the configured rate while no rate is enforced in xenstore. This creates an observability gap where administrators believe rate limiting is active when it is not.
VIF.qos_algorithm_params is a Map(String, String) field writable by vm-admin with zero per-key RBAC. The kbps key is parsed with Int64.of_string, which accepts negative integers.
The code path:
vm-admin sets kbps=-1: VIF.add_to_qos_algorithm_params(vif, "kbps", "-1")Int64.of_string at xapi_xenops.ml:795 - negative value accepted(-1L, 0L) is passed to xenopsddevice.ml:835-856:timeslice_us defaults to 50000L (since 0L <= 0L)bytes_per_interval = ((-1) * 1024 * 50000) / 1000000 = -51200-51200 > 0L is false - rate is silently droppedrate key is written to xenstoreAdditionally, the raw negative kbps value is written to the private xenstore path at device.ml:920-927 as Int64.to_string rate. While private xenstore is only dom0-readable and the value is integer-formatted (no path injection possible), the negative value persists as an anomalous entry.
Missing sign validation. Int64.of_string accepts negative integers. No check enforces kbps > 0 at the XAPI layer.
Silent rejection at consumer. xenopsd correctly rejects the negative computed rate but emits only a debug-level log message. The rejection is invisible to the management layer.
Database-xenstore state divergence. The XAPI database stores the negative value. Xenstore has no rate key. Monitoring tools that read the database report rate limiting as configured.
Missing RBAC protection. Zero map_keys_roles entries on the field. Any vm-admin can set arbitrary kbps values.
| Scenario | Impact | Pre-conditions | Status |
|---|---|---|---|
| Silent rate limit removal | VIF operates without rate limiting while XAPI shows negative kbps | vm-admin, ratelimit QoS type | Confirmed (live host) |
| Monitoring confusion | Management tools display negative rate value, confusing operators | vm-admin | Source-traced |
| Audit evasion | Rate limiting appears configured with a value that is syntactically valid but semantically invalid | vm-admin, compliance monitoring | Source-traced |
VIF.qos_algorithm_params:kbps in XAPI database against xenstore rate keykbps valuesdisclosure/vendor-detection-guidance.mdVIF.qos_algorithm_params records for negative kbps valueskbps value that is negative or zeroAdd write-time validation. Reject negative kbps values at the XAPI API layer. Enforce kbps > 0 and optionally kbps <= 100000000 (100 Gbps upper bound).
Propagate rejection errors. When xenopsd rejects a rate value, return an error to the XAPI caller rather than silently dropping the rate.
Add map_keys_roles protection. Restrict the kbps key to _R_POOL_OP to prevent vm-admin from modifying rate limits.
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
xapi_xenops.ml:781-808 (rate parsing, Int64.of_string accepts negatives), device.ml:835-856 (bytes_per_interval computation and bounds check), device.ml:920-927 (raw kbps written to private xenstore), datamodel.ml:1666-1681 (qos field definition, zero map_keys_roles)disclosure/advisories/vqp-security-advisory.md (VQP-3)research/investigations/vif-qos-algorithm-params.mdDiscovered and reported by Jakob Wolffhechel, Moksha.