upstream: be more careful when killing a ProxyCommand (including

implicit ProxyJump ones); observe if it already has exited via the main ssh.c
SIGCHLD handler and wrap the kill in sigprocmask() to avoid races.

Prevents SIGHUP from being delivered to an unrelated process if the proxy
command's PID is recycled.

Antropic ANT-2026-ODQD8QBH

OpenBSD-Commit-ID: 2fe79a15fcf1ff274f90a1d1dcd8cfe096d4a633
This commit is contained in:
djm@openbsd.org authored and Damien Miller committed 2026-10-30 20:18:06 +11:00
1 parent c41a6c4371
commit 45533eb438
3 files changed
+29 -7

No files matched your search

+6 -3
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: ssh.c,v 1.644 2026/10/30 06:47:17 djm Exp $ */
/* $OpenBSD: ssh.c,v 1.645 2026/10/30 08:17:19 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -2512,7 +2512,10 @@ main_sigchld_handler(int sig)
int status;
while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
(pid == -1 && errno == EINTR))
;
(pid == -1 && errno == EINTR)) {
/* Once reaped, the ProxyCommand's pid may be reused. */
if (pid > 0)
ssh_proxy_command_reaped(pid);
}
errno = save_errno;
}
+21 -3
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.390 2026/10/30 07:44:23 djm Exp $ */
/* $OpenBSD: sshconnect.c,v 1.391 2026/10/30 08:17:19 djm Exp $ */
/*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -60,7 +60,7 @@ struct sshkey *previous_host_key = NULL;
static int matching_host_key_dns = 0;
static pid_t proxy_command_pid = 0;
static volatile pid_t proxy_command_pid = 0;
/* import */
extern int debug_flag;
@@ -301,15 +301,33 @@ ssh_proxy_connect(struct ssh *ssh, const char *host, const char *host_arg,
return 0;
}
/*
* Called from the SIGCHLD handler for each child it reaps. Forget the
* proxy command once it has been reaped, as its pid may be reused.
*/
void
ssh_proxy_command_reaped(pid_t pid)
{
if (pid == proxy_command_pid)
proxy_command_pid = 0;
}
void
ssh_kill_proxy_command(void)
{
sigset_t nset, oset;
/*
* Send SIGHUP to proxy command if used. We don't wait() in
* case it hangs and instead rely on init to reap the child
* case it hangs and instead rely on init to reap the child.
* Block SIGCHLD so it can't be reaped between the check and kill().
*/
sigemptyset(&nset);
sigaddset(&nset, SIGCHLD);
sigprocmask(SIG_BLOCK, &nset, &oset);
if (proxy_command_pid > 1)
kill(proxy_command_pid, SIGHUP);
sigprocmask(SIG_SETMASK, &oset, NULL);
}
#ifdef HAVE_IFADDRS_H
+2 -1
View File
@@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.h,v 1.52 2026/08/03 06:47:24 djm Exp $ */
/* $OpenBSD: sshconnect.h,v 1.53 2026/10/30 08:17:19 djm Exp $ */
/*
* Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -74,6 +74,7 @@ int ssh_connect(struct ssh *, const char *, const char *,
struct addrinfo *, struct sockaddr_storage *, u_short,
int, int *, int);
void ssh_kill_proxy_command(void);
void ssh_proxy_command_reaped(pid_t);
void ssh_login(struct ssh *, Sensitive *, const char *,
struct sockaddr_storage *, u_short, struct passwd *, int,