ChainSafe / ChainSafe/docker-socket-policy
Rust fd://3 socket activation adopts the fd blindly — no validation it is a listening socket
- Dominant language
- Rust
- Stars
- 2
- Forks
- 0
- Avg merge
- 5h 17m
- Merged PRs (30d)
- 13
Description
## Summary
With `--listen-socket=fd://3`, the Rust implementation adopts fd 3 via `from_raw_fd` without verifying it is actually a listening AF_UNIX socket. Go's `net.FileListener` (`go/main.go:78`) rejects non-socket fds; Rust only surfaces the problem later as `io::Error` from `set_nonblocking`/`accept` (mitigated by the accept-error backoff added in #27 — no busy loop, but also no clear early failure).
Neither implementation checks the `LISTEN_PID`/`LISTEN_FDS` environment variables from the `sd_listen_fds` convention, so this is parity-plus hardening.
## Affected implementation(s)
- [x] Rust
- [ ] Go (partially validates via `net.FileListener`; also skips `LISTEN_FDS` env check)
## Expected behavior
`--listen-socket=fd://3` with an fd that is not a listening AF_UNIX socket should fail fast at startup with a clear error, not degrade into accept errors at runtime.
## Suggested fix
Before adopting the fd:
- `fstat` and check `S_IFSOCK`
- `getsockopt(SOL_SOCKET, SO_ACCEPTCONN)` to confirm it is listening
- Optionally validate `LISTEN_PID == getpid()` and `LISTEN_FDS >= 1` per the systemd convention (would also make sense in Go for parity)
Also worth a subprocess-based test that `dup2`s a real listener onto fd 3 and exercises the `fd://3` dispatch path end-to-end (currently only the fd-wrapping helper is unit-tested).
## Context
Split out from the review follow-ups on PR #27. Related: #25, #28.
Contributor guide
Assessment
This issue has not been assessed yet.