Problem Description
During Rosetta bootstrap on macOS, the runner initializes the Rosetta guest translator and passes the target guest binary path. In the implementation, the code hardcodes guest file descriptor 3 to store the guest binary's host file descriptor:
int bin_guest_fd = fd_alloc_at(3, FD_REGULAR, bin_host_fd, NULL);
This causes major issues for guest applications that rely on file descriptor 3 for their own purposes.
For example, when running apt update inside the guest, apt launches signature verification helpers (like gpgv) and sets up a status communication pipe mapped explicitly to guest file descriptor 3 (invoking gpgv --status-fd 3). Because the runner hijacks and overwrites guest fd 3 to point to the guest binary file descriptor, the status pipe is broken. As a result, apt cannot read the signature status, failing with:
Internal error: Good signature, but could not determine key fingerprint?!
Proposed Fix
Instead of hardcoding guest fd 3, allocate the guest file descriptor dynamically using the first unused fd, and pass it properly to the guest binary stack via AT_EXECFD.
- In
rosetta_finalize (src/core/rosetta.c), change fd_alloc_at(3, ...) to fd_alloc(...) to obtain a dynamic guest file descriptor, and return it.
- In
rosettad_set_binary_path (src/core/rosetta.c), format the target path dynamically to match the allocated file descriptor (i.e. /proc/self/fd/<bin_guest_fd>).
- In
guest_bootstrap_prepare and guest_bootstrap_rosetta_post_reset (src/core/bootstrap.c), capture the allocated descriptor returned from rosetta_finalize and supply it as the execfd parameter to build_linux_stack (which populates the AT_EXECFD auxiliary vector).
Problem Description
During Rosetta bootstrap on macOS, the runner initializes the Rosetta guest translator and passes the target guest binary path. In the implementation, the code hardcodes guest file descriptor
3to store the guest binary's host file descriptor:This causes major issues for guest applications that rely on file descriptor
3for their own purposes.For example, when running
apt updateinside the guest,aptlaunches signature verification helpers (likegpgv) and sets up a status communication pipe mapped explicitly to guest file descriptor3(invokinggpgv --status-fd 3). Because the runner hijacks and overwrites guest fd3to point to the guest binary file descriptor, the status pipe is broken. As a result,aptcannot read the signature status, failing with:Proposed Fix
Instead of hardcoding guest fd
3, allocate the guest file descriptor dynamically using the first unused fd, and pass it properly to the guest binary stack viaAT_EXECFD.rosetta_finalize(src/core/rosetta.c), changefd_alloc_at(3, ...)tofd_alloc(...)to obtain a dynamic guest file descriptor, and return it.rosettad_set_binary_path(src/core/rosetta.c), format the target path dynamically to match the allocated file descriptor (i.e./proc/self/fd/<bin_guest_fd>).guest_bootstrap_prepareandguest_bootstrap_rosetta_post_reset(src/core/bootstrap.c), capture the allocated descriptor returned fromrosetta_finalizeand supply it as theexecfdparameter tobuild_linux_stack(which populates theAT_EXECFDauxiliary vector).