mirror of
https://github.com/openssh/openssh-portable.git
synced 2026-11-06 05:16:43 +00:00
upstream: backout
> avoid race between multiple processes attempting to > > establish multiplexing control socket by moving socket creation earlier in > ssh(1)'s life. Patch from Jens Rosenboom via bz3971 It caused problems with ControlPersist sessions. Reported by semarie@ job@ OpenBSD-Commit-ID: b78a34d605c47cb145e16a3bba295caa0e9db680
This commit is contained in:
1 parent
e0f85d83cc
commit
fc6ca48d15
3 files changed
+39
-45
No files matched your search
+1
-2
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: clientloop.h,v 1.42 2026/09/22 03:22:00 djm Exp $ */
|
||||
/* $OpenBSD: clientloop.h,v 1.43 2026/09/23 21:42:39 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
@@ -78,7 +78,6 @@ void client_expect_confirm(struct ssh *, int, const char *,
|
||||
#define SSHMUX_COMMAND_CONNINFO 9 /* Show connection information */
|
||||
#define SSHMUX_COMMAND_CHANINFO 10 /* Show channels information */
|
||||
|
||||
int muxserver(const char *);
|
||||
void muxserver_listen(struct ssh *);
|
||||
int muxclient(const char *);
|
||||
void mux_exit_message(struct ssh *, Channel *, int);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: mux.c,v 1.115 2026/09/22 03:22:00 djm Exp $ */
|
||||
/* $OpenBSD: mux.c,v 1.116 2026/09/23 21:42:39 djm Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2002-2008 Damien Miller <djm@openbsd.org>
|
||||
*
|
||||
@@ -1315,20 +1315,21 @@ mux_tty_alloc_failed(struct ssh *ssh, Channel *c)
|
||||
sshbuf_free(m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a listening Unix domain socket for mux master or find out that
|
||||
* one exists already.
|
||||
*/
|
||||
int
|
||||
muxserver(const char *path)
|
||||
/* Prepare a mux master to listen on a Unix domain socket. */
|
||||
void
|
||||
muxserver_listen(struct ssh *ssh)
|
||||
{
|
||||
mode_t old_umask;
|
||||
char *tmp_path;
|
||||
char *orig_control_path = options.control_path;
|
||||
char rbuf[16+1];
|
||||
u_int i, r;
|
||||
int oerrno;
|
||||
|
||||
debug("trying to setup multiplex master socket at %s", path);
|
||||
if (options.control_path == NULL ||
|
||||
options.control_master == SSHCTL_MASTER_NO)
|
||||
return;
|
||||
|
||||
debug("setting up multiplex master socket");
|
||||
|
||||
/*
|
||||
* Use a temporary path before listen so we can pseudo-atomically
|
||||
@@ -1343,53 +1344,51 @@ muxserver(const char *path)
|
||||
'0' + r - 26 - 26;
|
||||
}
|
||||
rbuf[sizeof(rbuf) - 1] = '\0';
|
||||
xasprintf(&tmp_path, "%s.%s", path, rbuf);
|
||||
debug3_f("temporary control path %s", tmp_path);
|
||||
options.control_path = NULL;
|
||||
xasprintf(&options.control_path, "%s.%s", orig_control_path, rbuf);
|
||||
debug3_f("temporary control path %s", options.control_path);
|
||||
|
||||
old_umask = umask(0177);
|
||||
muxserver_sock = unix_listener(tmp_path, 64, 0);
|
||||
muxserver_sock = unix_listener(options.control_path, 64, 0);
|
||||
oerrno = errno;
|
||||
umask(old_umask);
|
||||
if (muxserver_sock < 0) {
|
||||
if (oerrno == EINVAL || oerrno == EADDRINUSE) {
|
||||
error("Temporary ControlSocket %s already exists", tmp_path);
|
||||
free(tmp_path);
|
||||
return -1;
|
||||
error("ControlSocket %s already exists, "
|
||||
"disabling multiplexing", options.control_path);
|
||||
disable_mux_master:
|
||||
if (muxserver_sock != -1) {
|
||||
close(muxserver_sock);
|
||||
muxserver_sock = -1;
|
||||
}
|
||||
free(orig_control_path);
|
||||
free(options.control_path);
|
||||
options.control_path = NULL;
|
||||
options.control_master = SSHCTL_MASTER_NO;
|
||||
return;
|
||||
} else {
|
||||
/* unix_listener() logs the error */
|
||||
cleanup_exit(255);
|
||||
}
|
||||
}
|
||||
set_nonblock(muxserver_sock);
|
||||
|
||||
/* Now atomically "move" the mux socket into position */
|
||||
if (link(tmp_path, path) != 0) {
|
||||
if (link(options.control_path, orig_control_path) != 0) {
|
||||
if (errno != EEXIST) {
|
||||
fatal_f("link mux listener %s => %s: %s",
|
||||
tmp_path, path,
|
||||
options.control_path, orig_control_path,
|
||||
strerror(errno));
|
||||
}
|
||||
debug("ControlSocket %s already exists", path);
|
||||
close(muxserver_sock);
|
||||
muxserver_sock = -1;
|
||||
}
|
||||
unlink(tmp_path);
|
||||
free(tmp_path);
|
||||
return muxserver_sock;
|
||||
error("ControlSocket %s already exists, disabling multiplexing",
|
||||
orig_control_path);
|
||||
unlink(options.control_path);
|
||||
goto disable_mux_master;
|
||||
}
|
||||
unlink(options.control_path);
|
||||
free(options.control_path);
|
||||
options.control_path = orig_control_path;
|
||||
|
||||
/* Prepare a mux master to listen on the previously created Unix domain socket. */
|
||||
void
|
||||
muxserver_listen(struct ssh *ssh)
|
||||
{
|
||||
if (options.control_path == NULL ||
|
||||
options.control_master == SSHCTL_MASTER_NO)
|
||||
return;
|
||||
|
||||
debug("setting up multiplex master socket");
|
||||
if (muxserver_sock < 0) {
|
||||
muxserver_sock = muxserver(options.control_path);
|
||||
}
|
||||
set_nonblock(muxserver_sock);
|
||||
|
||||
mux_listener_channel = channel_new(ssh, "mux listener",
|
||||
SSH_CHANNEL_MUX_LISTENER, muxserver_sock, muxserver_sock, -1,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: ssh.c,v 1.641 2026/09/22 03:22:00 djm Exp $ */
|
||||
/* $OpenBSD: ssh.c,v 1.642 2026/09/23 21:42:39 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
@@ -1634,11 +1634,7 @@ main(int ac, char **av)
|
||||
fatal("No ControlPath specified for \"-O\" command");
|
||||
if (options.control_path != NULL) {
|
||||
int sock;
|
||||
|
||||
if (muxclient_command == 0 &&
|
||||
(sock = muxserver(options.control_path)) >= 0) {
|
||||
debug("We will be multiplex master, not client.");
|
||||
} else if ((sock = muxclient(options.control_path)) >= 0) {
|
||||
if ((sock = muxclient(options.control_path)) >= 0) {
|
||||
if (ssh_packet_set_connection(ssh, sock, sock) == NULL)
|
||||
fatal("ssh_packet_set_connection failed");
|
||||
ssh_packet_set_mux(ssh);
|
||||
|
||||
Reference in new issue
Block a user