Stop using the WCONTINUED flag with waitpid(2).

We don't use it for anything other than a debug message and it will
cause problems when intercept mode starts using ptrace(2).
This commit is contained in:
Todd C. Miller
2022-04-29 08:02:57 -06:00
parent c7ed03c986
commit 46edc4e198
4 changed files with 48 additions and 48 deletions

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 1996, 1998-2005, 2008, 2009-2018 * Copyright (c) 1996, 1998-2005, 2008, 2009-2022
* Todd C. Miller <Todd.Miller@sudo.ws> * Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
@@ -290,12 +290,6 @@ extern int errno;
# define WCOREDUMP(x) ((x) & 0x80) # define WCOREDUMP(x) ((x) & 0x80)
#endif #endif
/* Older systems may not support WCONTINUED */
#if !defined(WCONTINUED) && !defined(WIFCONTINUED)
# define WCONTINUED 0
# define WIFCONTINUED(x) 0
#endif
/* W_EXITCODE is not POSIX but the encoding of wait status is. */ /* W_EXITCODE is not POSIX but the encoding of wait status is. */
#ifndef W_EXITCODE #ifndef W_EXITCODE
# define W_EXITCODE(ret, sig) ((ret) << 8 | (sig)) # define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 2009-2021 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 2009-2022 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -197,23 +197,23 @@ mon_handle_sigchld(struct monitor_closure *mc)
/* Read command status. */ /* Read command status. */
do { do {
pid = waitpid(mc->cmnd_pid, &status, WUNTRACED|WCONTINUED|WNOHANG); pid = waitpid(mc->cmnd_pid, &status, WUNTRACED|WNOHANG);
} while (pid == -1 && errno == EINTR); } while (pid == -1 && errno == EINTR);
switch (pid) { switch (pid) {
case -1:
if (errno != ECHILD) {
sudo_warn(U_("%s: %s"), __func__, "waitpid");
debug_return;
}
FALLTHROUGH;
case 0: case 0:
/* Nothing to wait for. */ /* Nothing to wait for. */
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: no process to wait for", sudo_debug_printf(SUDO_DEBUG_INFO, "%s: no process to wait for",
__func__); __func__);
debug_return; debug_return;
case -1:
sudo_warn(U_("%s: %s"), __func__, "waitpid");
debug_return;
} }
if (WIFCONTINUED(status)) { if (WIFSTOPPED(status)) {
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) resumed",
__func__, (int)mc->cmnd_pid);
} else if (WIFSTOPPED(status)) {
if (sig2str(WSTOPSIG(status), signame) == -1) if (sig2str(WSTOPSIG(status), signame) == -1)
(void)snprintf(signame, sizeof(signame), "%d", WSTOPSIG(status)); (void)snprintf(signame, sizeof(signame), "%d", WSTOPSIG(status));
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) stopped, SIG%s", sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) stopped, SIG%s",
@@ -230,7 +230,7 @@ mon_handle_sigchld(struct monitor_closure *mc)
mc->cmnd_pid = -1; mc->cmnd_pid = -1;
} else { } else {
sudo_debug_printf(SUDO_DEBUG_WARN, sudo_debug_printf(SUDO_DEBUG_WARN,
"%s: unexpected wait status %d for command (%d)", "%s: unexpected wait status 0x%x for command (%d)",
__func__, status, (int)mc->cmnd_pid); __func__, status, (int)mc->cmnd_pid);
} }
@@ -238,18 +238,15 @@ mon_handle_sigchld(struct monitor_closure *mc)
if (mc->cstat->type == CMD_INVALID) { if (mc->cstat->type == CMD_INVALID) {
/* /*
* Store wait status in cstat and forward to parent if stopped. * Store wait status in cstat and forward to parent if stopped.
* Parent does not expect SIGCONT so don't bother sending it.
*/ */
if (!WIFCONTINUED(status)) { mc->cstat->type = CMD_WSTATUS;
mc->cstat->type = CMD_WSTATUS; mc->cstat->val = status;
mc->cstat->val = status; if (WIFSTOPPED(status)) {
if (WIFSTOPPED(status)) { /* Save the foreground pgid so we can restore it later. */
/* Save the foreground pgid so we can restore it later. */ pid = tcgetpgrp(io_fds[SFD_FOLLOWER]);
pid = tcgetpgrp(io_fds[SFD_FOLLOWER]); if (pid != mc->mon_pgrp)
if (pid != mc->mon_pgrp) mc->cmnd_pgrp = pid;
mc->cmnd_pgrp = pid; send_status(mc->backchannel, mc->cstat);
send_status(mc->backchannel, mc->cstat);
}
} }
} else { } else {
sudo_debug_printf(SUDO_DEBUG_WARN, sudo_debug_printf(SUDO_DEBUG_WARN,

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 2009-2020 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 2009-2022 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -493,23 +493,23 @@ handle_sigchld_nopty(struct exec_closure_nopty *ec)
/* Read command status. */ /* Read command status. */
do { do {
pid = waitpid(ec->cmnd_pid, &status, WUNTRACED|WCONTINUED|WNOHANG); pid = waitpid(ec->cmnd_pid, &status, WUNTRACED|WNOHANG);
} while (pid == -1 && errno == EINTR); } while (pid == -1 && errno == EINTR);
switch (pid) { switch (pid) {
case -1:
if (errno != ECHILD) {
sudo_warn(U_("%s: %s"), __func__, "waitpid");
debug_return;
}
FALLTHROUGH;
case 0: case 0:
/* Nothing to wait for. */ /* Nothing to wait for. */
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: no process to wait for", sudo_debug_printf(SUDO_DEBUG_INFO, "%s: no process to wait for",
__func__); __func__);
debug_return; debug_return;
case -1:
sudo_warn(U_("%s: %s"), __func__, "waitpid");
debug_return;
} }
if (WIFCONTINUED(status)) { if (WIFSTOPPED(status)) {
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) resumed",
__func__, (int)ec->cmnd_pid);
} else if (WIFSTOPPED(status)) {
/* /*
* Save the controlling terminal's process group so we can restore it * Save the controlling terminal's process group so we can restore it
* after we resume, if needed. Most well-behaved shells change the * after we resume, if needed. Most well-behaved shells change the
@@ -594,10 +594,15 @@ handle_sigchld_nopty(struct exec_closure_nopty *ec)
(void)snprintf(signame, sizeof(signame), "%d", WTERMSIG(status)); (void)snprintf(signame, sizeof(signame), "%d", WTERMSIG(status));
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) killed, SIG%s", sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) killed, SIG%s",
__func__, (int)ec->cmnd_pid, signame); __func__, (int)ec->cmnd_pid, signame);
} else { } else if (WIFEXITED(status)) {
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) exited: %d", sudo_debug_printf(SUDO_DEBUG_INFO, "%s: command (%d) exited: %d",
__func__, (int)ec->cmnd_pid, WEXITSTATUS(status)); __func__, (int)ec->cmnd_pid, WEXITSTATUS(status));
} else {
sudo_debug_printf(SUDO_DEBUG_WARN,
"%s: unexpected wait status 0x%x for command (%d)",
__func__, status, (int)ec->cmnd_pid);
} }
/* Don't overwrite execve() failure with command exit status. */ /* Don't overwrite execve() failure with command exit status. */
if (ec->cstat->type == CMD_INVALID) { if (ec->cstat->type == CMD_INVALID) {
ec->cstat->type = CMD_WSTATUS; ec->cstat->type = CMD_WSTATUS;

View File

@@ -1,7 +1,7 @@
/* /*
* SPDX-License-Identifier: ISC * SPDX-License-Identifier: ISC
* *
* Copyright (c) 2009-2021 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 2009-2022 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -1049,17 +1049,20 @@ handle_sigchld_pty(struct exec_closure_pty *ec)
* Monitor process was signaled; wait for it as needed. * Monitor process was signaled; wait for it as needed.
*/ */
do { do {
pid = waitpid(ec->monitor_pid, &status, WUNTRACED|WCONTINUED|WNOHANG); pid = waitpid(ec->monitor_pid, &status, WUNTRACED|WNOHANG);
} while (pid == -1 && errno == EINTR); } while (pid == -1 && errno == EINTR);
switch (pid) { switch (pid) {
case -1:
if (errno != ECHILD) {
sudo_warn(U_("%s: %s"), __func__, "waitpid");
debug_return;
}
FALLTHROUGH;
case 0: case 0:
/* Nothing to wait for. */ /* Nothing to wait for. */
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: no process to wait for", sudo_debug_printf(SUDO_DEBUG_INFO, "%s: no process to wait for",
__func__); __func__);
debug_return; debug_return;
case -1:
sudo_warn(U_("%s: %s"), __func__, "waitpid");
debug_return;
} }
/* /*
@@ -1067,10 +1070,7 @@ handle_sigchld_pty(struct exec_closure_pty *ec)
* If it was stopped, we should stop too (the command keeps * If it was stopped, we should stop too (the command keeps
* running in its pty) and continue it when we come back. * running in its pty) and continue it when we come back.
*/ */
if (WIFCONTINUED(status)) { if (WIFSTOPPED(status)) {
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: monitor (%d) resumed",
__func__, (int)ec->monitor_pid);
} else if (WIFSTOPPED(status)) {
sudo_debug_printf(SUDO_DEBUG_INFO, sudo_debug_printf(SUDO_DEBUG_INFO,
"monitor stopped, suspending sudo"); "monitor stopped, suspending sudo");
n = suspend_sudo(ec, WSTOPSIG(status)); n = suspend_sudo(ec, WSTOPSIG(status));
@@ -1085,10 +1085,14 @@ handle_sigchld_pty(struct exec_closure_pty *ec)
sudo_debug_printf(SUDO_DEBUG_INFO, "%s: monitor (%d) killed, SIG%s", sudo_debug_printf(SUDO_DEBUG_INFO, "%s: monitor (%d) killed, SIG%s",
__func__, (int)ec->monitor_pid, signame); __func__, (int)ec->monitor_pid, signame);
ec->monitor_pid = -1; ec->monitor_pid = -1;
} else { } else if (WIFEXITED(status)) {
sudo_debug_printf(SUDO_DEBUG_INFO, sudo_debug_printf(SUDO_DEBUG_INFO,
"%s: monitor exited, status %d", __func__, WEXITSTATUS(status)); "%s: monitor exited, status %d", __func__, WEXITSTATUS(status));
ec->monitor_pid = -1; ec->monitor_pid = -1;
} else {
sudo_debug_printf(SUDO_DEBUG_WARN,
"%s: unexpected wait status 0x%x for monitor (%d)",
__func__, status, (int)ec->monitor_pid);
} }
debug_return; debug_return;
} }