3557db693da4320dc6c69525de6d42095372114b SUDO_1_9_10
d495c99554f7dfdc27126482644dd68463c54a35 SUDO_1_9_11
06b0f12fe91c43fbef0e774628516be7225ae883 SUDO_1_9_11p1
+9e4705cb1db53823e656dcf3fbbb9c54c3f95f48 SUDO_1_9_11p2
+What's new in Sudo 1.9.11p3
+
+ * Fixed "connection reset" errors on AIX when running shell scripts
+ with the "intercept" or "log_subcmds" sudoers options enabled.
+ Bug #1034.
+
+ * Fixed very slow execution of shell scripts when the "intercept"
+ or "log_subcmds" sudoers options are set on systems that enable
+ Nagle's algorithm on the loopback device, such as AIX.
+ Bug #1034.
+
What's new in Sudo 1.9.11p2
* Fixed a compilation error on Linux/x86_64 with the x32 ABI.
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for sudo 1.9.11p2.
+# Generated by GNU Autoconf 2.71 for sudo 1.9.11p3.
#
# Report bugs to <https://bugzilla.sudo.ws/>.
#
# Identity of this package.
PACKAGE_NAME='sudo'
PACKAGE_TARNAME='sudo'
-PACKAGE_VERSION='1.9.11p2'
-PACKAGE_STRING='sudo 1.9.11p2'
+PACKAGE_VERSION='1.9.11p3'
+PACKAGE_STRING='sudo 1.9.11p3'
PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/'
PACKAGE_URL=''
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures sudo 1.9.11p2 to adapt to many kinds of systems.
+\`configure' configures sudo 1.9.11p3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of sudo 1.9.11p2:";;
+ short | recursive ) echo "Configuration of sudo 1.9.11p3:";;
esac
cat <<\_ACEOF
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-sudo configure 1.9.11p2
+sudo configure 1.9.11p3
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by sudo $as_me 1.9.11p2, which was
+It was created by sudo $as_me 1.9.11p3, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by sudo $as_me 1.9.11p2, which was
+This file was extended by sudo $as_me 1.9.11p3, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
-sudo config.status 1.9.11p2
+sudo config.status 1.9.11p3
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
dnl
AC_PREREQ([2.70])
-AC_INIT([sudo], [1.9.11p2], [https://bugzilla.sudo.ws/], [sudo])
+AC_INIT([sudo], [1.9.11p3], [https://bugzilla.sudo.ws/], [sudo])
AC_CONFIG_HEADERS([config.h pathnames.h])
AC_CONFIG_SRCDIR([src/sudo.c])
AC_CONFIG_AUX_DIR([scripts])
sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid,
GETGROUPS_T **groupsp, int *ngroupsp)
{
+#ifdef __APPLE__
+ int *groups = (int *)*groupsp;
+#else
GETGROUPS_T *groups = *groupsp;
+#endif
int ngroups;
#ifndef HAVE_GETGROUPLIST_2
int grpsize, tries;
}
bool
-log_exit_status(int exit_status)
+log_exit_status(int status)
{
struct eventlog evlog;
int evl_flags = 0;
- int ecode = 0;
+ int exit_value = 0;
int oldlocale;
struct timespec run_time;
char sigbuf[SIG2STR_MAX];
- char *signame = NULL;
+ char *signal_name = NULL;
bool dumped_core = false;
bool ret = true;
debug_decl(log_exit_status, SUDOERS_DEBUG_LOGGING);
}
sudo_timespecsub(&run_time, &sudo_user.submit_time, &run_time);
- if (WIFEXITED(exit_status)) {
- ecode = WEXITSTATUS(exit_status);
- } else if (WIFSIGNALED(exit_status)) {
- int signo = WTERMSIG(exit_status);
+ if (WIFEXITED(status)) {
+ exit_value = WEXITSTATUS(status);
+ } else if (WIFSIGNALED(status)) {
+ int signo = WTERMSIG(status);
if (signo <= 0 || sig2str(signo, sigbuf) == -1)
(void)snprintf(sigbuf, sizeof(sigbuf), "%d", signo);
- signame = sigbuf;
- ecode = signo | 128;
- dumped_core = WCOREDUMP(exit_status);
+ signal_name = sigbuf;
+ exit_value = signo | 128;
+ dumped_core = WCOREDUMP(status);
} else {
- sudo_warnx("invalid exit status 0x%x", exit_status);
+ sudo_warnx("invalid exit status 0x%x", status);
ret = false;
goto done;
}
SET(evl_flags, EVLOG_MAIL_ONLY);
}
evlog.run_time = run_time;
- evlog.exit_value = ecode;
- evlog.signal_name = signame;
+ evlog.exit_value = exit_value;
+ evlog.signal_name = signal_name;
evlog.dumped_core = dumped_core;
if (!eventlog_exit(&evlog, evl_flags))
ret = false;
#include <sys/socket.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#if defined(HAVE_STDINT_H)
# include <stdint.h>
case false:
goto done;
default:
- if (errno == EINTR || errno == EAGAIN)
+ if (errno == EINTR || errno == EAGAIN) {
debug_return_bool(true);
+ sudo_debug_printf(
+ SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "reading intercept token");
+ }
sudo_warn("recv");
goto done;
}
nread = recv(fd, &req_len, sizeof(req_len), 0);
if (nread != sizeof(req_len)) {
if (nread == -1) {
- if (errno == EINTR || errno == EAGAIN)
+ if (errno == EINTR || errno == EAGAIN) {
+ sudo_debug_printf(
+ SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "reading intercept message size");
debug_return_bool(true);
+ }
sudo_warn("recv");
}
goto done;
/* EOF, other side must have exited. */
goto done;
case -1:
- if (errno == EINTR || errno == EAGAIN)
+ if (errno == EINTR || errno == EAGAIN) {
+ sudo_debug_printf(
+ SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "reading intercept message");
debug_return_bool(true);
+ }
sudo_warn("recv");
goto done;
default:
nwritten = send(fd, closure->buf + closure->off,
closure->len - closure->off, 0);
if (nwritten == -1) {
- if (errno == EINTR || errno == EAGAIN)
+ if (errno == EINTR || errno == EAGAIN) {
+ sudo_debug_printf(
+ SUDO_DEBUG_WARN|SUDO_DEBUG_ERRNO|SUDO_DEBUG_LINENO,
+ "writing intercept message");
debug_return_bool(true);
+ }
sudo_warn("send");
goto done;
}
struct sudo_event_base *evbase = sudo_ev_get_base(&closure->ev);
struct sockaddr_in sin;
socklen_t sin_len = sizeof(sin);
- int client_sock, flags;
+ int client_sock, flags, on = 1;
debug_decl(intercept_accept_cb, SUDO_DEBUG_EXEC);
if (closure->state != RECV_CONNECTION) {
if (flags != -1)
(void)fcntl(client_sock, F_SETFL, flags | O_NONBLOCK);
+ /* Send data immediately, we need low latency IPC. */
+ (void)setsockopt(client_sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+
/*
* Create a new intercept closure and register an event for client_sock.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#if defined(HAVE_STDINT_H)
# include <stdint.h>
debug_decl(recv_intercept_response, SUDO_DEBUG_EXEC);
/* Read message size (uint32_t in host byte order). */
- nread = recv(fd, &res_len, sizeof(res_len), 0);
- if ((size_t)nread != sizeof(res_len)) {
- if (nread == 0) {
+ for (;;) {
+ nread = recv(fd, &res_len, sizeof(res_len), 0);
+ if (nread == ssizeof(res_len))
+ break;
+ switch (nread) {
+ case 0:
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"unexpected EOF reading response size");
- } else {
- sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ break;
+ case -1:
+ if (errno == EINTR)
+ continue;
+ sudo_debug_printf(
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
"error reading response size");
+ break;
+ default:
+ sudo_debug_printf(
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
+ "error reading response size: short read");
+ break;
}
- goto done;
+ goto done;
}
if (res_len > MESSAGE_SIZE_MAX) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
case -1:
if (errno == EINTR)
continue;
- sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
+ sudo_debug_printf(
+ SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO,
"error reading response");
goto done;
default:
{
InterceptResponse *res = NULL;
static bool initialized;
- int fd = -1;
+ int flags, fd = -1;
char **p;
debug_decl(sudo_interposer_init, SUDO_DEBUG_EXEC);
}
/*
+ * We don't want to use non-blocking I/O.
+ */
+ flags = fcntl(fd, F_GETFL, 0);
+ if (flags != -1)
+ (void)fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
+
+ /*
* Send InterceptHello message to over the fd.
*/
if (!send_client_hello(fd))
intercept_connect(void)
{
int sock = -1;
+ int on = 1;
struct sockaddr_in sin;
debug_decl(command_allowed, SUDO_DEBUG_EXEC);
goto done;
}
+ /* Send data immediately, we need low latency IPC. */
+ (void)setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
+
if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
sudo_warn("connect");
close(sock);