What
When a request carries no containerId, resolve_container_name mints one:
src/backends/lxc/common/src/state_aware.rs:104-107
if request.container_id.is_empty() {
return Ok(format!("mxc-{}", mint_random_token()));
}
mint_random_token (id.rs:20-23) is 4 bytes, so 8 hex characters -- 32 bits.
provision then treats an existing container of that name as a success:
src/backends/lxc/common/src/state_aware.rs:479-487
let created = !container.is_defined();
if created {
container.create(..)?;
}
So a generated name that collides with an existing container is silently
adopted: provision returns Ok with created: false, and the caller
believes it owns a fresh container it did not create.
Why it matters
Adoption is intentional and documented for a user-supplied id
(lxc_bindings.rs:615) -- the caller named that container, so reattaching to it
is the useful behavior. An auto-generated name carries the opposite intent:
the caller asked for a new container and has no way to know it was handed
someone else's. Both take the identical branch today.
Fix
Have the generated-name path retry rather than adopt: mint, check is_defined,
mint again on collision, and fail after a small bounded number of attempts.
Roughly 10-15 lines, confined to the container_id.is_empty() branch.
Note that MAX_CONTAINER_NAME_LEN = 20 (state_aware.rs:84) is enforced only
for user-supplied ids, and mxc- plus 16 hex characters is 20, so widening the
token would also fit. Keep that out of this fix -- mint_random_token lives
in id.rs and is shared across backends, so widening it is a separate change
with a wider blast radius. Retry-not-adopt is correct on its own and does not
depend on the entropy question.
Provenance
Reported by Copilot on PR #849, verified live against that PR's HEAD. Held out
of the PR deliberately: it changes provision's success semantics, which warrants
its own review.
What
When a request carries no
containerId,resolve_container_namemints one:src/backends/lxc/common/src/state_aware.rs:104-107mint_random_token(id.rs:20-23) is 4 bytes, so 8 hex characters -- 32 bits.provisionthen treats an existing container of that name as a success:src/backends/lxc/common/src/state_aware.rs:479-487So a generated name that collides with an existing container is silently
adopted: provision returns
Okwithcreated: false, and the callerbelieves it owns a fresh container it did not create.
Why it matters
Adoption is intentional and documented for a user-supplied id
(
lxc_bindings.rs:615) -- the caller named that container, so reattaching to itis the useful behavior. An auto-generated name carries the opposite intent:
the caller asked for a new container and has no way to know it was handed
someone else's. Both take the identical branch today.
Fix
Have the generated-name path retry rather than adopt: mint, check
is_defined,mint again on collision, and fail after a small bounded number of attempts.
Roughly 10-15 lines, confined to the
container_id.is_empty()branch.Note that
MAX_CONTAINER_NAME_LEN = 20(state_aware.rs:84) is enforced onlyfor user-supplied ids, and
mxc-plus 16 hex characters is 20, so widening thetoken would also fit. Keep that out of this fix --
mint_random_tokenlivesin
id.rsand is shared across backends, so widening it is a separate changewith a wider blast radius. Retry-not-adopt is correct on its own and does not
depend on the entropy question.
Provenance
Reported by Copilot on PR #849, verified live against that PR's HEAD. Held out
of the PR deliberately: it changes provision's success semantics, which warrants
its own review.