Description
The idToGuestCID function in pkg/unikontainers/vaccel.go generates vhost-vsock Context Identifiers (CIDs) by summing the ASCII values of a container ID and applying mod 97. This restricts the entire output space to just 97 possible CIDs (range [3, 99]).
Since standard container IDs (e.g., from containerd) are 64-character hex strings, this constrained output space leads to frequent collisions. In a multi-container vAccel deployment, the probability of a CID collision exceeds 50% with just 13 concurrent containers.
When a collision occurs, the hypervisor passes the duplicate guest-cid to the kernel, which rejects the binding with EADDRINUSE. Because urunc does not currently implement collision detection or retry logic during the Exec phase, the container initialization fails.
Furthermore, because the hashing mechanism relies on a simple character sum, container IDs that are anagrams of each other (which is common with hex-encoded strings) will deterministically collide.
Root Cause
pkg/unikontainers/vaccel.go does the (sum % 97) + 3 math.
pkg/unikontainers/unikontainers.go calls it during container Exec().
- The hypervisors (
qemu.go, firecracker.go, cloud_hypervisor.go) then pass this blindly to the kernel.
Reproducer for Anagram Collisions
def id_to_guest_cid(id_str):
return (sum(ord(c) for c in id_str) % 97) + 3
id1 = "abcdef0123456789" * 4
id2 = "9876543210fedcba" * 4
# Both IDs share the same character distribution
assert id_to_guest_cid(id1) == id_to_guest_cid(id2) # Evaluates to 29
Proposed Solution
Replace the character sum with a non-cryptographic hash (e.g., hash/fnv) over the container ID, and map it to the full available vhost-vsock CID range ([3, 1<<32 - 1]).
Alternatively, if CIDs must be strictly deterministic and collision-free across arbitrary host states, implement a probe-and-retry mechanism to verify CID availability before executing the VMM.
Description
The
idToGuestCIDfunction inpkg/unikontainers/vaccel.gogenerates vhost-vsock Context Identifiers (CIDs) by summing the ASCII values of a container ID and applyingmod 97. This restricts the entire output space to just 97 possible CIDs (range [3, 99]).Since standard container IDs (e.g., from containerd) are 64-character hex strings, this constrained output space leads to frequent collisions. In a multi-container vAccel deployment, the probability of a CID collision exceeds 50% with just 13 concurrent containers.
When a collision occurs, the hypervisor passes the duplicate
guest-cidto the kernel, which rejects the binding withEADDRINUSE. Becauseuruncdoes not currently implement collision detection or retry logic during theExecphase, the container initialization fails.Furthermore, because the hashing mechanism relies on a simple character sum, container IDs that are anagrams of each other (which is common with hex-encoded strings) will deterministically collide.
Root Cause
pkg/unikontainers/vaccel.godoes the(sum % 97) + 3math.pkg/unikontainers/unikontainers.gocalls it during containerExec().qemu.go,firecracker.go,cloud_hypervisor.go) then pass this blindly to the kernel.Reproducer for Anagram Collisions
Proposed Solution
Replace the character sum with a non-cryptographic hash (e.g.,
hash/fnv) over the container ID, and map it to the full available vhost-vsock CID range ([3, 1<<32 - 1]).Alternatively, if CIDs must be strictly deterministic and collision-free across arbitrary host states, implement a probe-and-retry mechanism to verify CID availability before executing the VMM.