Skip to content

Commit ac7b8bc

Browse files
author
Roy Lin
committed
fix(box): avoid CString panic on a NUL workdir without a rootfs
configure_child_process built a CString from the working directory unconditionally and .expect()ed it, but build_command only rejects an embedded NUL in the workdir when a rootfs is set. A rootfs-less exec with a NUL byte in working_dir could therefore panic the exec connection thread. The workdir CString is now built only when a rootfs is present (its sole use is chdir after chroot), where the NUL was already rejected. Closes the last of the 16 findings from this session's adversarial review. Verified: build + clippy clean; ReadonlyPaths / seccomp-default / RunAsUser critest specs still pass (chroot+rootfs exec path unaffected).
1 parent 48d5816 commit ac7b8bc

1 file changed

Lines changed: 11 additions & 3 deletions

File tree

src/guest/init/src/exec_server.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,13 @@ fn configure_child_process(
851851

852852
let rootfs = rootfs
853853
.map(|rootfs| CString::new(rootfs.as_bytes()).expect("rootfs path was pre-validated"));
854-
let workdir = CString::new(workdir.as_bytes()).expect("working directory was pre-validated");
854+
// workdir (for chdir) is only used when chrooting into a rootfs, where
855+
// build_command has already rejected an embedded NUL. Build the CString only
856+
// in that case so a workdir containing a NUL with no rootfs set cannot panic
857+
// this exec thread.
858+
let workdir = rootfs
859+
.as_ref()
860+
.map(|_| CString::new(workdir.as_bytes()).expect("working directory was pre-validated"));
855861

856862
// Build the seccomp BPF filter BEFORE fork: building allocates, and
857863
// allocating in the post-fork child is not async-signal-safe (malloc may
@@ -870,8 +876,10 @@ fn configure_child_process(
870876
if libc::chroot(rootfs.as_ptr()) != 0 {
871877
return Err(std::io::Error::last_os_error());
872878
}
873-
if libc::chdir(workdir.as_ptr()) != 0 {
874-
return Err(std::io::Error::last_os_error());
879+
if let Some(workdir) = workdir.as_ref() {
880+
if libc::chdir(workdir.as_ptr()) != 0 {
881+
return Err(std::io::Error::last_os_error());
882+
}
875883
}
876884
}
877885
// Apply supplemental groups while still privileged — setgroups

0 commit comments

Comments
 (0)