-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Summary
Layered OCI image extraction fails with refusing to write through symlink when a higher layer legitimately replaces a symlink (created by a lower layer) with a real file. Extraction falls back to flat mode, losing the layer caching benefit.
Reproduction
Build a layered Alpine image where the base layer has busybox (which creates /usr/bin/env as a symlink) and a subsequent layer installs coreutils (which replaces /usr/bin/env with a real binary):
# base image
FROM alpine:3.21
RUN apk add --no-cache coreutils findutilsWhen propolis extracts this image with layered extraction enabled, layer 1 (the apk add layer) tries to write the real coreutils /usr/bin/env over the busybox symlink from layer 0 and hits the symlink traversal guard:
level=WARN msg="layered extraction failed, falling back to flat extraction"
err="apply layer 1 (sha256:6a4114a...): copy file usr/bin/env: refusing to write through symlink: /path/to/cache/tmp-rootfs-.../usr/bin/env"
Expected behavior
Layered extraction should handle the case where a layer replaces an existing symlink with a real file. The symlink traversal protection should detect that the target path is the symlink itself (not traversing through one to reach a different location) and allow the replacement.
Context
This was discovered in waggle after upgrading to propolis v0.0.15 and introducing a shared base image with coreutils. The flat extraction fallback works correctly — VMs boot and run fine — but layer-level caching is not effective since every extraction falls back to flat mode.
Environment
- propolis v0.0.15
- Alpine 3.21 base images
coreutilspackage triggers the symlink replacement