ChainSafe / ChainSafe/docker-socket-policy

Rust fd://3 socket activation adopts the fd blindly — no validation it is a listening socket

Open
#29 0 comments 0 reactions 0 assignees View on GitHub
Priority: P3 Type: Enhancement
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.