MOKSHA-2026-0080: I/O Scheduler Sysfs Injection via SR.other_config scheduler

Advisory IDMOKSHA-2026-0080
Semantic IDSOC-1
Published2026-04-24
CVSS 3.13.8 Low
CVSS 3.1 VectorAV:N/AC:L/PR:H/UI:N/S:U/C:N/I:L/A:N
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 ObjectSR
XAPI Fieldother_config:scheduler
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 write an arbitrary string to the kernel's I/O scheduler sysfs interface by setting the scheduler key in SR.other_config. The SM driver reads this value at SR.py:203-224 (block_setscheduler) and passes it directly to util.set_scheduler, which writes it to /sys/block/<dev>/queue/scheduler without any XAPI-side validation. The kernel itself validates the value - only registered scheduler names are accepted - limiting direct exploitation. The concern is the architectural pattern: user-controlled data from an XAPI map field flows directly to a kernel control interface with zero intermediate validation. The SR.other_config field has no map_keys_roles entries for infrastructure keys.

Vulnerability Description

SR.other_config is a Map(String, String) field defined at datamodel.ml:4930-4935 with _R_POOL_OP as the minimum write role.

The data flow from XAPI to kernel sysfs:

pool-operator writes SR.other_config:scheduler = VALUE
    |
    v
XAPI stores to database (zero validation)
    |
    v
SR driver operation (attach/scan/etc.)
    |
    v
SR.block_setscheduler(dev) at SR.py:203-224
    reads other_config["scheduler"]
    if sched not in self.scheds: scheds = [sched]   # attacker value
    |
    v
util.set_scheduler(realdev, scheds) at util.py:1156-1178
    |
    v
set_scheduler_sysfs_node("/sys/block/DEV", scheds)
    open("/sys/block/DEV/queue/scheduler", "w")
    file.write("%s\n" % sched)   # attacker value written to kernel sysfs

The block_setscheduler method reads the scheduler value from SR.other_config and attempts to set it as the I/O scheduler for the SR's block devices. If the value is not in the list of known schedulers (self.scheds), it is used directly as the scheduler name.

The kernel's sysfs handler for /sys/block/*/queue/scheduler validates the incoming value against registered schedulers. Unknown scheduler names are silently rejected. This kernel-side validation prevents arbitrary code execution through this path.

Valid scheduler names that an attacker could set to alter I/O behavior:

Switching an SR's block devices to a suboptimal scheduler can degrade storage performance for all VMs using that SR.

Root Causes

  1. Missing write-time validation. XAPI stores the value without checking it against known scheduler names. The validation happens only at the kernel sysfs write, well after the attacker-controlled value has traversed multiple components.

  2. Missing RBAC protection. SR.other_config has map_keys_roles entries only for UI keys (folder, XenCenter.CustomFields.*). The scheduler key is writable by any pool-operator.

  3. Direct kernel interface write. User-controlled data from an API-level map field flows to a kernel sysfs control file without intermediate sanitization. Even though the kernel validates the value, this architectural pattern is unsafe: the XAPI layer should validate before reaching the kernel interface.

  4. set_other_config RBAC bypass. The set_other_config method replaces the entire map atomically and bypasses map_keys_roles per-key checks.

Affected Systems

Directly Affected

Indirectly Affected

Exploitation Scenarios

Scenario Impact Pre-conditions Status
Scheduler change to noop I/O ordering disabled, performance degradation under contention pool-operator, block-device-backed SR Source-traced
Scheduler change to CFQ Throughput reduction on SSDs (CFQ not optimized for flash storage) pool-operator, SSD-backed SR Source-traced
Invalid scheduler name Write to sysfs fails silently, SM driver logs error pool-operator Source-traced
BOC-1 chain vm-admin changes scheduler across all SRs via RBAC collapse vm-admin, BOC-1 Source-traced

Chaining Analysis

Detection

Remediation

Short-Term Mitigations

Long-Term Fix

Add write-time validation. Validate the scheduler value against a whitelist of known Linux I/O schedulers (none, noop, deadline, cfq, bfq, mq-deadline, kyber) at XAPI write time. Reject unknown values.

Add map_keys_roles protection. Restrict the scheduler key to _R_POOL_ADMIN in datamodel.ml.

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