Skip to content

Cross-platform packager: OCI symlink resolution, rewrite-include, rtld_audit removal#741

Open
wdcui wants to merge 4 commits intowdcui/stacked/pr1b-trampoline-formatfrom
wdcui/stacked/pr2-packager-crossplatform
Open

Cross-platform packager: OCI symlink resolution, rewrite-include, rtld_audit removal#741
wdcui wants to merge 4 commits intowdcui/stacked/pr1b-trampoline-formatfrom
wdcui/stacked/pr2-packager-crossplatform

Conversation

@wdcui
Copy link
Copy Markdown
Member

@wdcui wdcui commented Apr 3, 2026

Summary

Make litebox_packager compile and work on non-Linux hosts (primarily Windows) for the OCI image packaging path.

  • Remove crate-level #![cfg(target_os = "linux")] gate; gate only ldd-based host mode behind #[cfg(target_os = "linux")]
  • Add cross-platform file_mode() helper (MetadataExt::mode() on Unix, permission-based heuristic elsewhere)
  • Cross-platform OCI symlink handling: Track symlinks in-memory (DeferredSymlink) instead of creating OS symlinks (which require special privileges on Windows). Resolve symlink chains through an in-memory map and materialize as file copies or directory placeholders
  • Add --rewrite-include CLI flag for dlopen'd libraries (e.g., NSS modules) that aren't discovered by the automatic dependency scan
  • Add OCI platform resolver to always pull linux/amd64 images regardless of host platform
  • Change Bun-packaged executable detection from a warning to a hard error (these can't be rewritten)
  • Switch tar format from GNU to USTAR (required by the no_std tar reader)
  • Normalize \ to / in tar entry paths for Windows compatibility
  • Delete the no-op build.rs (rtld_audit fully removed from packager)

Bug fixes (not in feature branch)

  • Whiteout symlink pruning: OCI opaque whiteouts (.wh..wh..opq) and regular whiteouts (.wh.<name>) removed files from disk but didn't prune corresponding entries from the in-memory symlinks vec, causing materialize_symlinks() to resurrect deleted symlinks
  • Degenerate symlink target resolution: normalize_path() could return an empty PathBuf for targets with excess .. segments, causing resolve_symlink_in_rootfs() to match the rootfs directory itself

Stack

Test results

  • 219 tests: 204 passed, 15 failed (all TUN/EPERM — no device permissions), 34 skipped
  • fmt ✅, clippy ✅

wdcui added 3 commits April 2, 2026 22:23
…olution, rewrite-include flag

Make litebox_packager compile and work on non-Linux hosts (primarily
Windows) by:

- Remove #![cfg(target_os = "linux")] crate-level gate and the dual-main
  pattern; gate only the host-mode code path behind cfg(target_os)
- Add file_mode() helper with unix/non-unix variants to replace
  MetadataExt::mode() calls
- Extract run_host_mode() behind #[cfg(target_os = "linux")]
- Track OCI layer symlinks in-memory instead of creating OS symlinks
  (Windows requires special privileges for symlinks); materialize them
  after all layers are extracted via resolve_symlink_in_rootfs()
- Add is_unix_absolute(), strip_unix_root(), normalize_path() helpers
  for cross-platform path handling
- Force linux/amd64 platform when pulling OCI images
- Normalize path separators to Unix-style in tar entries
- Add --rewrite-include CLI flag for dlopen'd libraries
- Change Bun executable detection from warning to hard error
- Switch tar headers from GNU to UStar format
…tion

Two bugs found during review:

1. Opaque whiteouts (.wh..wh..opq) and regular whiteouts (.wh.<name>)
   removed files from disk but did not prune corresponding entries from
   the in-memory symlinks vec. This caused materialize_symlinks() to
   resurrect deleted symlinks that a later layer intended to remove.

2. resolve_symlink_in_rootfs() could return Some(rootfs) when a
   degenerate symlink target with excess .. segments normalized to an
   empty path via normalize_path(). rootfs.join("") == rootfs, which
   exists as a directory, causing the entire rootfs to be treated as
   a resolution target. Guard against empty rel_path at function entry.
- Store Unix permission modes from tar headers in a HashMap during
  extraction, so permission bits are accurate on non-Unix hosts (Windows)
  instead of relying on the file_mode() heuristic which returns wrong
  answers (0o755 for most files).
- Build symlink_map once in pull_and_extract and pass through to
  materialize_symlinks and scan_rootfs (was duplicated in both).
- Add lookup_mode() helper that prefers tar header permissions, falls
  back to file_mode(), defaults to 0o644.
- Add existence check for --rewrite-include in finalize_tar (was missing).
- Remove redundant --include/--rewrite-include parsing from run_host_mode.
- Replace Bun test with rewrite_elf_skips_non_elf_files test.
- Add 22 unit tests for normalize_path, is_unix_absolute, strip_unix_root,
  resolve_symlink_in_rootfs, and lookup_mode.
- Add litebox_packager to build_and_test_windows CI job.
@wdcui wdcui requested a review from sangho2 April 3, 2026 21:12
@wdcui wdcui marked this pull request as ready for review April 3, 2026 21:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant