You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ssh-agent: pin the peer process with a pidfd before reading /proc #61
nodkey ssh-agent reads the claimed context (the command lines of ssh and up to 3 parents, and NODKEY_REASON) from /proc/<pid>, with the PID from SO_PEERCRED. Once the /proc/<pid> directory is open, the reads stay on that process. But if the process that connected has already ended and its PID was given to a new process, the open itself can land on the new process; a parent's PID can be reused the same way.
Only claimed text is affected: the broker shows the host and the user from its own checks, and another user's environment cannot be read. Found in the review of #13.
What
Get a pidfd with SO_PEERPIDFD (Linux 6.5 and newer), open /proc/<pid> and then check with the pidfd that the process is still the same one (for example pidfd_send_signal with signal 0, or PIDFD_GET_INFO on newer kernels).
On older kernels keep today's behaviour.
Done when
A test where the peer exits before the read: no context from a new process with the same PID is sent.
A test where the peer exits before the read: no context from a new process with the same PID is sent.TestPeerExitedBeforeRead (internal/client/sshagent_pidfd_linux_test.go): a real pidfd of a process that ended, and a /proc tree where a new process has its PID; the sign request has no command lines and no reason, the new process's text is not in the log, and one line says ssh has ended. Also the case where the kernel has pidfds but gives none. TestClaimedContextNotRunning and TestClaimedContextParentChanged (sshagent_proc_test.go) cover the check of the process and of a reused parent PID. A mutation check (no pidfd check) makes TestPeerExitedBeforeRead fail.
THREAT-MODEL describes it. In T2, where the claimed context of nodkey ssh-agent is described (T31 is now about the log of the agent). DESIGN.md section 6 too.
Older kernels (no SO_PEERPIDFD) keep the old behaviour, with the new parent check.
Activity
docs: describe the pidfd check of ssh-agent
fix: review notes on the pidfd check
fix: say when ssh has ended, and correct the threat model
groupsky commentedon Nov 4, 2026
Done in #156 (squash commit e59592e).
TestPeerExitedBeforeRead(internal/client/sshagent_pidfd_linux_test.go): a real pidfd of a process that ended, and a /proc tree where a new process has its PID; the sign request has no command lines and no reason, the new process's text is not in the log, and one line says ssh has ended. Also the case where the kernel has pidfds but gives none.TestClaimedContextNotRunningandTestClaimedContextParentChanged(sshagent_proc_test.go) cover the check of the process and of a reused parent PID. A mutation check (no pidfd check) makesTestPeerExitedBeforeReadfail.nodkey ssh-agentis described (T31 is now about the log of the agent). DESIGN.md section 6 too.Older kernels (no
SO_PEERPIDFD) keep the old behaviour, with the new parent check.