Skip to content

feat(ssh-agent): pin the peer process with a pidfd before reading /proc - #156

Merged
groupsky merged 5 commits into
mainfrom
feat/61-pidfd
Nov 4, 2026
Merged

groupsky merged 5 commits into
mainfrom
feat/61-pidfd

Conversation

@groupsky

@groupsky groupsky commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Refs #61

nodkey ssh-agent reads the claimed context of an SSH login from /proc/<pid>. If ssh ended and its process ID went to a new process, the open of /proc/<pid> could land on the new process. A parent's ID could be used again the same way.

What changes

  • The agent gets a pidfd of the process that connected (SO_PEERPIDFD, Linux 6.5 and newer). After it opens /proc/<pid>, it checks with the pidfd that the process still runs (pidfd_send_signal with signal 0). If not, the sign request goes without the command lines and the reason.
  • If the kernel has SO_PEERPIDFD but gives no pidfd (for example the process already ended), the request also goes without them.
  • A parent counts only if its child, after the open of the parent's directory, still names it as its parent. A process whose parent ended gets another parent, so a reused parent ID is seen.
  • When the context is dropped for this reason, the agent writes one fixed line: "ssh has ended".
  • On a kernel without SO_PEERPIDFD the agent works as before (with the parent check).

Choices

  • Signal 0 with pidfd_send_signal instead of PIDFD_GET_INFO: it works on every kernel that has SO_PEERPIDFD (6.5), and it is one syscall.
  • The syscall numbers are constants in the code, not golang.org/x/sys/unix: no new direct dependency. They are the same on amd64 and arm64, the only release targets.

Progress

  • A test where the peer exits before the read: no context from a new process with the same PID is sent (TestPeerExitedBeforeRead, TestClaimedContextNotRunning, TestClaimedContextParentChanged).
  • THREAT-MODEL describes it: in T2, where the claimed context of ssh-agent is described (T31 is now about the log of the agent). DESIGN.md section 6 too.
  • Review subagent (fixed: a doc sentence, a comment, close-on-exec in a test).
  • Security review (fixed: the threat model text for old kernels; a log line when the context is dropped). Fix round: nothing left.
  • Green CI, merge.

@groupsky
groupsky marked this pull request as ready for review November 4, 2026 06:46
@groupsky
groupsky merged commit e59592e into main Nov 4, 2026
9 checks passed
@groupsky
groupsky deleted the feat/61-pidfd branch November 4, 2026 06:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant