You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(oci): block host-file deletion via malicious-image whiteout symlink escape (#140)
A hostile OCI image could DELETE arbitrary files/directories on the HOST when
pulled. Layer extraction's whiteout handling is hand-rolled and only guarded the
FINAL path component with symlink_metadata — it never checked the PARENT. A layer
can legally extract an absolute symlink (`esc -> /etc`; absolute symlink targets
are normal in images and the `..`-component check does not inspect symlink
targets), then a whiteout whose parent is that symlink:
- `esc/.wh.passwd` -> remove_path(target/esc/passwd) follows esc -> deletes
/etc/passwd on the HOST
- `esc/.wh..wh..opq` -> read_dir(target/esc) follows esc -> wipes ALL of /etc
on the HOST (mass deletion)
This happens host-side during `pull`/`run`, BEFORE the microVM boots, so VM
isolation gives no protection — any user pulling an untrusted image is exposed.
The WRITE path is NOT affected: tar's `unpack_in` already refuses to write
through a symlinked parent (verified by test); only the hand-rolled whiteout
DELETE paths were vulnerable.
Fix: resolve the whiteout parent WITHIN the rootfs via `resolve_within`
(canonicalize + `starts_with(target_dir)`) before deleting; skip + warn if it
escapes. Intra-rootfs symlinks stay allowed (the image may mutate its own
files) — only escapes past the extraction target are blocked.
Tests (TDD, encode the SECURE expectation — a failure is a real escape):
whiteout_does_not_delete_through_symlinked_parent,
opaque_whiteout_does_not_wipe_through_symlinked_parent,
layer_entry_cannot_write_through_symlinked_parent (already safe via unpack_in).
All 12 oci::layers tests pass (3 new + existing whiteout/opaque regression).
Co-authored-by: Roy Lin <roylin@a3s.box>
0 commit comments