Daniel Kahn Gillmor
2025-Apr-16 00:18 UTC
[PATCH] ssh-agent: exit 0 from SIGTERM under systemd socket-activation
When the ssh-agent service is configured to be launched under systemd
socket-activation, the user can inspect the status of the agent with
something like:
systemctl --user status ssh-agent.service
If the user does:
systemctl --user stop ssh-agent.service
it causes the `systemd --user` supervisor to send a SIGTERM to the
agent, which terminates while leaving the systemd-managed socket in
place. That's good, and as expected. (If the user wants to close the
socket, they can do "systemctl --user stop ssh-agent.socket" instead)
But because ssh-agent exits with code 2 in response to a SIGTERM, the
supervisor marks the service as "failed", even though the state of the
supervised service is exactly the same as during session startup (not
running, ready to launch when a client connects to the socket).
This change makes ssh-agent exit cleanly (code 0) in response to a
SIGTERM when launched under socket activation. This aligns the systemd
supervisor's understanding of the state of supervised ssh-agent with
reality.
Signed-off-by: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
---
ssh-agent.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/ssh-agent.c b/ssh-agent.c
index 55b9f44f4..9617e6ee0 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -2238,6 +2238,7 @@ main(int ac, char **av)
size_t npfd = 0;
u_int maxfds;
sigset_t nsigset, osigset;
+ int socket_activated = 0;
/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
sanitise_stdfd();
@@ -2389,6 +2390,7 @@ main(int ac, char **av)
fatal("bad LISTEN_PID: %d vs pid %d", pid, getpid());
debug("using socket activation on fd=3");
sock = 3;
+ socket_activated = 1;
}
/* Otherwise, create private directory for agent socket */
@@ -2522,7 +2524,7 @@ skip:
sigprocmask(SIG_BLOCK, &nsigset, &osigset);
if (signalled_exit != 0) {
logit("exiting on signal %d", (int)signalled_exit);
- cleanup_exit(2);
+ cleanup_exit((signalled_exit == SIGTERM && socket_activated) ? 0 :
2);
}
if (signalled_keydrop) {
logit("signal %d received; removing all keys",
--
2.47.2
Daniel Kahn Gillmor
2025-Apr-16 15:38 UTC
[PATCH] ssh-agent: exit 0 from SIGTERM under systemd socket-activation
On Tue 2025-04-15 20:18:34 -0400, Daniel Kahn Gillmor wrote:> This change makes ssh-agent exit cleanly (code 0) in response to a > SIGTERM when launched under socket activation. This aligns the systemd > supervisor's understanding of the state of supervised ssh-agent with > reality.I've also proposed this on github as: https://github.com/openssh/openssh-portable/pull/565 Thanks for considering this cleanup! --dkg -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 227 bytes Desc: not available URL: <http://lists.mindrot.org/pipermail/openssh-unix-dev/attachments/20250416/a6aa1c19/attachment-0001.asc>
Daniel Kahn Gillmor
2025-May-07 22:18 UTC
[PATCH] ssh-agent: exit 0 from SIGTERM under systemd socket-activation
Just a gentle nudge here: if it's possible to get a review of the
proposed change below, i'd appreciate it!
--dkg
On Tue 2025-04-15 20:18:34 -0400, Daniel Kahn Gillmor
wrote:> When the ssh-agent service is configured to be launched under systemd
> socket-activation, the user can inspect the status of the agent with
> something like:
>
> systemctl --user status ssh-agent.service
>
> If the user does:
>
> systemctl --user stop ssh-agent.service
>
> it causes the `systemd --user` supervisor to send a SIGTERM to the
> agent, which terminates while leaving the systemd-managed socket in
> place. That's good, and as expected. (If the user wants to close the
> socket, they can do "systemctl --user stop ssh-agent.socket"
instead)
>
> But because ssh-agent exits with code 2 in response to a SIGTERM, the
> supervisor marks the service as "failed", even though the state
of the
> supervised service is exactly the same as during session startup (not
> running, ready to launch when a client connects to the socket).
>
> This change makes ssh-agent exit cleanly (code 0) in response to a
> SIGTERM when launched under socket activation. This aligns the systemd
> supervisor's understanding of the state of supervised ssh-agent with
> reality.
>
> Signed-off-by: Daniel Kahn Gillmor <dkg at fifthhorseman.net>
> ---
> ssh-agent.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/ssh-agent.c b/ssh-agent.c
> index 55b9f44f4..9617e6ee0 100644
> --- a/ssh-agent.c
> +++ b/ssh-agent.c
> @@ -2238,6 +2238,7 @@ main(int ac, char **av)
> size_t npfd = 0;
> u_int maxfds;
> sigset_t nsigset, osigset;
> + int socket_activated = 0;
>
> /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
> sanitise_stdfd();
> @@ -2389,6 +2390,7 @@ main(int ac, char **av)
> fatal("bad LISTEN_PID: %d vs pid %d", pid, getpid());
> debug("using socket activation on fd=3");
> sock = 3;
> + socket_activated = 1;
> }
>
> /* Otherwise, create private directory for agent socket */
> @@ -2522,7 +2524,7 @@ skip:
> sigprocmask(SIG_BLOCK, &nsigset, &osigset);
> if (signalled_exit != 0) {
> logit("exiting on signal %d", (int)signalled_exit);
> - cleanup_exit(2);
> + cleanup_exit((signalled_exit == SIGTERM && socket_activated) ?
0 : 2);
> }
> if (signalled_keydrop) {
> logit("signal %d received; removing all keys",
> --
> 2.47.2
>
> _______________________________________________
> openssh-unix-dev mailing list
> openssh-unix-dev at mindrot.org
> https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 227 bytes
Desc: not available
URL:
<http://lists.mindrot.org/pipermail/openssh-unix-dev/attachments/20250507/c5e04c27/attachment-0001.asc>
Possibly Parallel Threads
- [Bug 3531] New: Ssh will not exit when it receives SIGTERM before calling poll in client_wait_until_can_do_something until some events happen.
- suggested fix for the sigchld race
- [PATCH] ssh-agent: add systemd socket-based activation
- Possibly Missing Syscalls from Seccomp Filter
- does nmbd self sigterm ?