A vm-admin can corrupt Change Block Tracking (CBT) metadata by injecting a crafted content_id value into VDI.other_config. The content_id key is used by the XAPI storage bridge (storage_smapiv1.ml) to track VDI content identity across activate/deactivate/clone cycles. Incremental backup solutions use content_id to determine the base snapshot for changed-block calculations. A forged UUID causes the backup system to use an incorrect base, missing changed blocks and producing backups that silently lose data on restore. The attack requires a single API call and produces no security alerts.
VDI.other_config is a Map(String, String) field writable by vm-admin. The content_id key participates in a lifecycle managed by the XAPI storage bridge.
(* storage_smapiv1.ml *)
(* VDI.activate (RW): remove content_id - content is about to change *)
Db.VDI.remove_from_other_config ~__context ~self ~key:"content_id" (* line 524-525 *)
(* VDI.deactivate: generate new content_id - content is now stable *)
if not (List.mem_assoc "content_id" other_config) then
Db.VDI.add_to_other_config ~__context ~self ~key:"content_id"
~value:Uuidx.(to_string (make ())) (* line 557-559 *)
(* VDI.clone: inherit content_id from parent - same content *)
let content_id =
List.assoc "content_id"
(Db.VDI.get_other_config ~__context ~self:clonee) (* line 682-684 *)
The content_id value has no format validation. A vm-admin can:
Forge a content_id. Set content_id to match a different VDI's identity. The backup system treats the VDIs as having identical content when they do not, causing the incremental backup to skip blocks that have changed.
Remove content_id. Force XAPI to regenerate a new UUID on the next deactivate cycle, breaking the chain of identity that backup systems rely on for incremental tracking.
Set an invalid content_id. Inject a non-UUID string that may cause parsing failures in backup systems that expect UUID format.
CBT-based incremental backup works by comparing the current VDI's content_id against the base snapshot's content_id. If they match, the backup system assumes the content is identical and only tracks blocks changed since the snapshot. A forged content_id that matches a stale or incorrect base causes the backup to:
Missing RBAC protection. VDI.other_config has zero map_keys_roles entries for content_id. Any vm-admin can modify it.
No format validation. The content_id value is accepted as any arbitrary string. No UUID format enforcement, no check against known VDI identities.
Backend trust assumption. The XAPI storage bridge assumes content_id is only modified by XAPI's own lifecycle code. No mechanism distinguishes XAPI-set values from user-injected values.
Silent failure mode. Backup systems that rely on content_id for incremental tracking have no way to detect a forged value. The corruption is silent until a restore reveals missing data.
content_id for incremental tracking| Scenario | Impact | Pre-conditions | Status |
|---|---|---|---|
| content_id forgery | Incremental backups miss changed blocks, silent data loss on restore | CBT-enabled VDI, backup system using content_id | Confirmed (injection path code-traced; content_id lifecycle verified in storage_smapiv1.ml) |
| content_id removal | Backup chain broken, forces full backup or causes backup failure | CBT-enabled VDI | Modeled (follows from lifecycle analysis) |
| Cross-VDI identity collision | Two VDIs with same content_id, backup system may confuse them | Multiple VDIs under backup | Modeled |
| Bulk corruption via BOC-1 | Root access enables bulk content_id modification across all VDIs in the pool | BOC-1 available | Modeled (amplification chain) |
VDI.other_config writes for the content_id key from API users (as opposed to internal XAPI operations)content_id values that do not match UUID formatcontent_id consistency across snapshot chains: parent and clone should share the same content_id unless modifieddisclosure/vendor-detection-guidance.mdVDI.other_config records for unexpected content_id valuesAdd map_keys_roles. Protect content_id in datamodel.ml at _R_POOL_ADMIN to prevent vm-admin from modifying it.
Format validation. Enforce UUID format when content_id is set via the API. Reject non-UUID values.
Internal-only flag. Mark content_id as an internally-managed key that should not be writable through external API calls. The XAPI storage bridge should be the only writer.
Upstream patches exist. They are held privately pending coordinated disclosure.
Disclosure:
storage_smapiv1.ml:524-525 (content_id removal on activate), storage_smapiv1.ml:557-559 (content_id generation on deactivate), storage_smapiv1.ml:682-684 (content_id inheritance on clone), datamodel.ml (VDI field definition)disclosure/advisories/doc-security-advisory.md (DOC-4)research/investigations/vdi-other-config.mdDiscovered and reported by Jakob Wolffhechel, Moksha.