MOKSHA-2026-0062: Rate Limit Removal via kbps=0 in VIF.qos_algorithm_params

Advisory IDMOKSHA-2026-0062
Semantic IDVQP-2
Published2026-04-24
CVSS 3.15.3 Medium
CVSS 3.1 VectorAV:N/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:N
CVSS 4.05.3 Medium
CVSS 4.0 VectorAV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
XAPI ObjectVIF
XAPI Fieldqos_algorithm_params:kbps
Entry Rolevm-admin
ResearcherJakob Wolffhechel, Moksha

Affected Products

VendorProductVersions
Citrix / Cloud Software GroupXenServer / Citrix Hypervisorall versions (shared XAPI codebase)
VatesXCP-ng8.3.0

Summary

A vm-admin in XAPI-based hypervisors (XenServer, XCP-ng) can cause a VIF's network rate limiting to be silently disabled by setting kbps=0 in VIF.qos_algorithm_params. XAPI accepts the zero value without validation and stores it in the database. When the VIF is plugged, xenopsd computes bytes_per_interval = 0, which fails the bounds check at device.ml:850 (bytes_per_interval > 0L), causing the rate limit to be silently dropped. The XAPI database continues to show rate limiting as "configured" while no rate is enforced in xenstore. Administrators and automation tools that check the XAPI database see a false positive - they believe rate limiting is active when it is not.

Vulnerability Description

VIF.qos_algorithm_params is a Map(String, String) field writable by vm-admin with zero per-key RBAC. When VIF.qos_algorithm_type is set to ratelimit, the kbps key specifies the rate limit in kilobits per second.

The code path:

  1. vm-admin sets kbps=0: VIF.add_to_qos_algorithm_params(vif, "kbps", "0")
  2. XAPI parses kbps via Int64.of_string at xapi_xenops.ml:795 - zero is accepted
  3. Rate tuple (0L, timeslice_us) is passed to xenopsd
  4. xenopsd computes at device.ml:835-856:
    • timeslice_us defaults to 50000L (50ms) since 0L <= 0L
    • bytes_per_interval = (0 * 1024 * 50000) / 1000000 = 0
  5. Bounds check: 0 > 0L is false - rate is silently dropped
  6. No rate key is written to xenstore
  7. VIF operates without rate limiting
  8. XAPI database still shows kbps=0 as the configured rate

This is a defense-in-depth success at the xenopsd layer - the invalid rate is correctly rejected. The vulnerability is the observability gap: XAPI accepts the value without error, stores it in the database, and provides no feedback that the rate limit is not active. The gap between what the database says and what is actually enforced is the security issue.

Root Causes

  1. Missing write-time validation. XAPI accepts kbps=0 without rejecting it. A rate of zero kilobits per second is never a valid rate limit.

  2. Silent rejection at consumer. xenopsd correctly rejects the computed rate but emits only a debug-level log. No error propagates back to the API caller or the management layer.

  3. Database-xenstore state divergence. The XAPI database reflects what was written via the API. Xenstore reflects what was actually applied. When these diverge, monitoring and audit tools that read the XAPI database report a false positive.

  4. Missing RBAC protection. VIF.qos_algorithm_params has zero map_keys_roles entries. Any vm-admin can set or remove rate limits without restriction.

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

Scenario Impact Pre-conditions Status
Silent rate limit removal VIF operates without rate limiting while XAPI shows it as configured vm-admin, ratelimit QoS type Confirmed (live host)
Compliance evasion Audit tools report rate limiting active; actual enforcement is absent vm-admin, compliance monitoring Source-traced
Bandwidth monopolization VM consumes unbounded bandwidth while appearing rate-limited vm-admin, shared network Source-traced

Chaining Analysis

Detection

Remediation

Short-Term Mitigations

Long-Term Fix

Add write-time validation. Reject kbps values of zero and negative numbers at the XAPI API layer. Return an API error to the caller rather than accepting an invalid configuration.

Propagate rejection errors. When xenopsd rejects a rate value, propagate the error back to the XAPI layer so the database can reflect the actual enforcement state.

Add map_keys_roles protection. Restrict the kbps key to _R_POOL_OP so vm-admin cannot unilaterally modify rate limits.

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