docker: use the container's chown (not busybox) in vendor volume/perms path

The vendor skip-init path (_setup_skip_init_volumes, _fix_permissions) runs
`/gns3/bin/busybox chown` inside the container via docker exec. busybox is
statically linked, and its chown dlopens NSS modules (libnss_*) from the
container; on NOS images whose glibc differs from the host's (e.g. Cisco
XRd) that mismatches and aborts with the glibc assertion
`_dl_call_libc_early_init: sym != NULL` (SIGABRT). The per-file chown loop
then crash-loops, and the resulting core-dump storm -- processed by the
host's systemd-coredump -- cascades into host device rescans, reconnecting
USB / resetting audio / corrupting the journal on every XRd start.

cp/chmod/find/stat don't touch NSS and work fine on busybox, so only chown
is affected. Prefer the container's own coreutils chown
(`command -v chown && chown ...`), falling back to busybox chown only when
the container ships no chown (minimal images, where the glibc matches and
busybox is safe).
This commit is contained in:
YueGuobin 2026-08-14 01:27:18 +08:00
parent 347537f1b3
commit b928a2f48a
No known key found for this signature in database

View File

@ -183,6 +183,12 @@ class VendorDockerVM(DockerVM):
target = f"/gns3volumes{volume}"
log.debug("Docker container '%s' fix ownership on %s", self._name, target)
try:
# chown prefers the container's own coreutils over /gns3/bin/busybox:
# busybox is static, and its chown dlopens NSS modules from the
# container, which mismatch the static glibc and abort (glibc
# "sym != NULL") on NOS images whose glibc differs from the host's
# (e.g. Cisco XRd). It falls back to busybox on minimal images that
# ship no chown. cp/chmod/find/stat don't use NSS, so stay busybox.
process = await asyncio.subprocess.create_subprocess_exec(
"docker",
"exec",
@ -195,7 +201,7 @@ class VendorDockerVM(DockerVM):
f" | /gns3/bin/busybox xargs -0 /gns3/bin/busybox stat -c '%a:%u:%g:%n' > \"{target}/.gns3_perms\""
")"
f' && /gns3/bin/busybox chmod -R u+rX "{target}"'
f' && /gns3/bin/busybox chown {uid}:{gid} -R "{target}"',
f' && ( command -v chown >/dev/null 2>&1 && chown {uid}:{gid} -R "{target}" || /gns3/bin/busybox chown {uid}:{gid} -R "{target}" )',
stderr=asyncio.subprocess.PIPE,
)
except OSError as e:
@ -233,7 +239,10 @@ class VendorDockerVM(DockerVM):
f'/gns3/bin/busybox mount --bind "{vol_target}" "{volume}" && '
f'while IFS=: read -r PERMS OWNER GROUP FILE; do '
f' [ -L "$FILE" ] || /gns3/bin/busybox chmod "$PERMS" "$FILE" 2>/dev/null; '
f' /gns3/bin/busybox chown -h "$OWNER:$GROUP" "$FILE" 2>/dev/null; '
# chown: prefer the container's coreutils, fall back to busybox
# (see _fix_permissions -- static busybox chown aborts on
# mismatched-glibc NOS images like XRd).
f' ( command -v chown >/dev/null 2>&1 && chown -h "$OWNER:$GROUP" "$FILE" || /gns3/bin/busybox chown -h "$OWNER:$GROUP" "$FILE" ) 2>/dev/null; '
f'done < "{volume}/.gns3_perms"'
)
# fmt: on