2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 09:57:41 +00:00

Defer installing the SIGCHLD handler until after non-job commands run.

Lock the socket dir to avoid races in open_persistent_connection().
Also avoid using "ssh -f" since that may return before the socket is created.
Strip carriage returns from log when running in a pty.
This commit is contained in:
Todd C. Miller 2022-12-07 07:44:44 -07:00
parent 2e322c0943
commit 31684dccc0

View File

@ -135,7 +135,6 @@ my $INFO = "INFO";
$INFO = "USR1" unless exists $SIG{INFO}; $INFO = "USR1" unless exists $SIG{INFO};
$SIG{$INFO} = \&info; $SIG{$INFO} = \&info;
$SIG{CHLD} = \&reaper;
$SIG{HUP} = \&shut_down; $SIG{HUP} = \&shut_down;
$SIG{INT} = \&shut_down; $SIG{INT} = \&shut_down;
$SIG{QUIT} = \&shut_down; $SIG{QUIT} = \&shut_down;
@ -177,6 +176,10 @@ foreach my $vm_host (keys %vm_servers) {
} }
} }
# We want to catch the jobs as they finish but not any of the other
# commands started via run() or system() above.
$SIG{CHLD} = \&reaper;
# We limit the number of concurrent jobs a single host can support. # We limit the number of concurrent jobs a single host can support.
# In the future, this may be set on a per-host basis. # In the future, this may be set on a per-host basis.
# If a host already is at the limit, we queue the job until a worker # If a host already is at the limit, we queue the job until a worker
@ -625,6 +628,7 @@ sub run_remote_command {
for (;;) { for (;;) {
pump $h; pump $h;
if (defined($outbuf)) { if (defined($outbuf)) {
$outbuf =~ s/\r+$//gm;
print $output $outbuf; print $output $outbuf;
undef $outbuf; undef $outbuf;
} }
@ -645,16 +649,24 @@ sub open_persistent_connection {
my ($outbuf, @cmdline); my ($outbuf, @cmdline);
# Handle user@host form # Handle user@host form
my @tmp = split(/\@/, $dest); $dest =~ /([^@]+)$/;
my $host = pop(@tmp); my $host = $1;
my @ssh_opts = qw(-f -M -N -oControlPersist=yes); my @ssh_opts = qw(-M -N -oControlPersist=yes);
push(@ssh_opts, "-S", "$sockets/$host"); push(@ssh_opts, "-S", "$sockets/$host");
push(@ssh_opts, "-oProxyCommand=$proxy") if defined($proxy); push(@ssh_opts, "-oProxyCommand=$proxy") if defined($proxy);
# Lock socket dir to prevent race conditions
sysopen(SOCKDIR, $sockets, O_RDONLY) || die "$0: unable to open $sockets: $!\n";
flock(SOCKDIR, LOCK_EX) || die "$0: unable to lock $sockets: $!\n";
if (-S "$sockets/$host") { if (-S "$sockets/$host") {
@cmdline = ("ssh", "-S", "$sockets/$host", "-Ocheck", $host); @cmdline = ("ssh", "-S", "$sockets/$host", "-Ocheck", $host);
run(\@cmdline, '<', \undef, '>&', \$outbuf, debug => $debug); run(\@cmdline, '<', \undef, '>&', \$outbuf, debug => $debug);
if ($outbuf =~ /^Master running/) {
close(SOCKDIR);
return 0;
}
return 0 if $outbuf =~ /^Master running/; return 0 if $outbuf =~ /^Master running/;
unlink("$sockets/$host"); unlink("$sockets/$host");
} }
@ -662,15 +674,11 @@ sub open_persistent_connection {
@cmdline = ssh_cmdline($dest, undef, @ssh_opts); @cmdline = ssh_cmdline($dest, undef, @ssh_opts);
run(\@cmdline, '<', \undef, '>&', \$outbuf, debug => $debug); run(\@cmdline, '<', \undef, '>&', \$outbuf, debug => $debug);
if (length($outbuf) > 0) { if (length($outbuf) > 0) {
if ($outbuf =~ /already exists, disabling multiplexing/) {
# We may lose the race to create the socket, that's OK.
$? = 0;
} else {
$output = \*STDERR unless defined($output); $output = \*STDERR unless defined($output);
print $output $outbuf; print $output $outbuf;
} }
}
close(SOCKDIR);
return $?; return $?;
} }