Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions crates/native-sidecar/src/execution/javascript/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,12 +225,31 @@ pub(crate) fn deferred_kernel_wait_request_for_process(
return Ok(None);
}
let fd = javascript_sync_rpc_arg_u32(&request.args, 0, "filesystem write fd")?;
// Mapped host fds live in the per-process map, NOT the kernel fd table, so
// stat'ing one here raised `EBADF: bad file descriptor 1000000000` on EVERY
// guest file write. That error escaped the process-event pump: it used to
// kill the whole sidecar (LT-011 cross-tenant DoS) and, once the pump
// stopped propagating it, left the guest's sync-RPC response undelivered
// until the 31 s bridge deadline (LT-024). A mapped host fd is host-backed
// and can never be a kernel pipe, so deferral never applies to it.
//
// The ownership lookup is authoritative and is preferred over a numeric
// `fd >= MAPPED_HOST_FD_START` range test: an fd in that range that this
// process does NOT own should still fall through to the kernel and be
// rejected there, rather than being silently treated as host-backed.
if process.mapped_host_fd(fd).is_some() {
return Ok(None);
}
let stat = kernel
.fd_stat(EXECUTION_DRIVER_NAME, process.kernel_pid, fd)
.map_err(kernel_error)?;
let stat = match kernel.fd_stat(EXECUTION_DRIVER_NAME, process.kernel_pid, fd) {
Ok(stat) => stat,
// Defense in depth for the whole class: any fd this kernel does not own
// is by definition not a kernel pipe, so it is not deferrable. Report
// "no deferral" rather than failing the write with an unrelated errno —
// the normal write path re-checks ownership and raises the correct
// errno there, so the loud failure is preserved, not swallowed.
Err(error) if error.code() == "EBADF" => return Ok(None),
Err(error) => return Err(kernel_error(error)),
};
if stat.filetype != agentos_kernel::fd_table::FILETYPE_PIPE {
return Ok(None);
}
Expand Down