MOKSHA-2026-0041: Rolling Upgrade State Injection via Pool.other_config

Advisory IDMOKSHA-2026-0041
Semantic IDPLOC-1
Published2026-04-24
CVSS 3.16.5 Medium
CVSS 3.1 VectorAV:N/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H
CVSS 4.05.1 Medium
CVSS 4.0 VectorAV:N/AC:L/AT:N/PR:H/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
XAPI ObjectPool
XAPI Fieldother_config:rolling_upgrade_in_progress
Entry Rolepool-operator
ResearcherJakob Wolffhechel, Moksha

Affected Products

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

Summary

A pool-operator in XAPI-based hypervisors (XenServer, XCP-ng) can inject a fake rolling upgrade state by writing the rolling_upgrade_in_progress key to Pool.other_config. The mere presence of this key - regardless of value - causes helpers.ml:718-719 to return true, disabling version compatibility checks, altering pool behavior during operations, and preventing detection of version mismatches across the pool. The key has no map_keys_roles protection and no write-time validation, and with BOC-1 chaining, a vm-admin can reach this vector via RBAC collapse.

Vulnerability Description

Pool.other_config is a Map(String, String) field writable by pool-operator. The rolling_upgrade_in_progress key controls whether the pool operates in rolling upgrade mode - a transient state intended for use only during actual version upgrades.

The code path:

  1. pool-operator calls Pool.add_to_other_config(pool, "rolling_upgrade_in_progress", "") (any value works)
  2. helpers.ml:718-719 checks List.mem_assoc "rolling_upgrade_in_progress" - a pure presence check
  3. The function returns true regardless of the key's value
  4. Multiple consumers alter behavior:
    • db_gc.ml:161-163 - triggers rolling upgrade resynchronization
    • xapi_host_helpers.ml:624-625 - disables software version checking during pool join
    • xapi-autostart-vms script - suppresses VM auto-start

No validation occurs at write time. The key is not protected by map_keys_roles. The Pool.other_config field only protects UI keys (folder, XenCenter.CustomFields.*, EMPTY_FOLDERS) at _R_VM_OP.

Root Causes

  1. Missing RBAC protection. Pool.other_config has zero map_keys_roles entries for infrastructure keys. The rolling_upgrade_in_progress key inherits the class default _R_POOL_OP.

  2. Presence-only check. The consumer at helpers.ml:718-719 uses List.mem_assoc - the key's mere existence triggers upgrade mode. There is no validation of expected values, no cross-check against actual upgrade state, and no timestamp or session binding.

  3. Missing write-time validation. No mechanism verifies that a rolling upgrade is actually in progress before accepting this key.

  4. Insufficient logging. No security-level log event is generated when this key is written.

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

Scenario Impact Pre-conditions Status
Fake upgrade mode Disables version compatibility checks, allows mismatched hosts to join pool pool-operator Source-traced
VM auto-start suppression VMs fail to auto-start after host reboot during fake upgrade state pool-operator Source-traced
BOC-1 chain vm-admin uses BOC-1 S3 to self-grant pool-operator, then injects fake upgrade state vm-admin, BOC-1 Source-traced

Chaining Analysis

Detection

Remediation

Short-Term Mitigations

Long-Term Fix

Protect the key via map_keys_roles. Add rolling_upgrade_in_progress to Pool.other_config map_keys_roles at _R_LOCAL_ROOT_ONLY or _R_POOL_ADMIN in datamodel_pool.ml. This key should only be set by internal XAPI upgrade orchestration, not by API users.

Add state validation. The consumer at helpers.ml:718-719 should cross-check against actual upgrade state (e.g., verify that an RPU task exists) rather than relying solely on a user-writable key.

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