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:
@@ -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))
|
||||||
|
@@ -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,9 +238,7 @@ 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)) {
|
||||||
@@ -250,7 +248,6 @@ mon_handle_sigchld(struct monitor_closure *mc)
|
|||||||
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,
|
||||||
"%s: not overwriting command status %d,%d with %d,%d",
|
"%s: not overwriting command status %d,%d with %d,%d",
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user