summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@sudo.ws>2022-06-08 08:33:16 -0600
committerTodd C. Miller <Todd.Miller@sudo.ws>2022-06-08 08:33:16 -0600
commita781a5b2506e120a059bce2a64664a93fa1004a5 (patch)
tree3c04ab07531840f8ee3bf2f4f4aa403db371b433
parent58656bda244b5815a9a21dcb23344cf58dd42403 (diff)
parent1466a4c8dc712e3c710e36d28e4cb52418b87aa4 (diff)
downloadsudo-a781a5b2506e120a059bce2a64664a93fa1004a5.tar.gz
Merge sudo 1.9.11p1 from tip.SUDO_1_9_11p1
-rw-r--r--NEWS16
-rw-r--r--config.h.in6
-rwxr-xr-xconfigure26
-rw-r--r--configure.ac6
-rw-r--r--docs/sudoers.man.in12
-rw-r--r--docs/sudoers.mdoc.in12
-rw-r--r--include/sudo_event.h8
-rw-r--r--lib/protobuf-c/protobuf-c.c38
-rw-r--r--lib/util/event_select.c16
-rw-r--r--logsrvd/logsrvd.c9
-rw-r--r--logsrvd/logsrvd_relay.c4
-rw-r--r--logsrvd/sendlog.c4
-rw-r--r--plugins/sudoers/sudoers.in2
-rw-r--r--src/exec_ptrace.h1
-rw-r--r--src/exec_pty.c36
-rw-r--r--src/sudo_exec.h4
-rw-r--r--src/sudo_noexec.c6
17 files changed, 117 insertions, 89 deletions
diff --git a/NEWS b/NEWS
index b6251fc24..9700b0200 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,19 @@
+What's new in Sudo 1.9.11p1
+
+ * Correctly handle EAGAIN in the I/O read/right events. This fixes
+ a hang seen on some systems when piping a large amount of data
+ through sudo, such as via rsync. Bug #963.
+
+ * Changes to avoid implementation or unspecified behavior when
+ bit shifting signed values in the protobuf library.
+
+ * Fixed a compilation error on Linux/aarch64.
+
+ * Fixed the configure check for seccomp(2) support on Linux.
+
+ * Corrected the EBNF specification for tags in the sudoers manual
+ page. GitHub issue #153.
+
What's new in Sudo 1.9.11
* Fixed a crash in the Python module with Python 3.9.10 on some
diff --git a/config.h.in b/config.h.in
index d0be95822..c9c024a15 100644
--- a/config.h.in
+++ b/config.h.in
@@ -175,9 +175,9 @@
don't. */
#undef HAVE_DECL_QUAD_MIN
-/* Define to 1 if you have the declaration of `SECCOMP_SET_MODE_FILTER', and
- to 0 if you don't. */
-#undef HAVE_DECL_SECCOMP_SET_MODE_FILTER
+/* Define to 1 if you have the declaration of `SECCOMP_MODE_FILTER', and to 0
+ if you don't. */
+#undef HAVE_DECL_SECCOMP_MODE_FILTER
/* Define to 1 if you have the declaration of `setauthdb', and to 0 if you
don't. */
diff --git a/configure b/configure
index 33182d022..14d14976d 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for sudo 1.9.11.
+# Generated by GNU Autoconf 2.71 for sudo 1.9.11p1.
#
# Report bugs to <https://bugzilla.sudo.ws/>.
#
@@ -621,8 +621,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sudo'
PACKAGE_TARNAME='sudo'
-PACKAGE_VERSION='1.9.11'
-PACKAGE_STRING='sudo 1.9.11'
+PACKAGE_VERSION='1.9.11p1'
+PACKAGE_STRING='sudo 1.9.11p1'
PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/'
PACKAGE_URL=''
@@ -1640,7 +1640,7 @@ if test "$ac_init_help" = "long"; then
# 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.11 to adapt to many kinds of systems.
+\`configure' configures sudo 1.9.11p1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1706,7 +1706,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of sudo 1.9.11:";;
+ short | recursive ) echo "Configuration of sudo 1.9.11p1:";;
esac
cat <<\_ACEOF
@@ -1996,7 +1996,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-sudo configure 1.9.11
+sudo configure 1.9.11p1
generated by GNU Autoconf 2.71
Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2653,7 +2653,7 @@ cat >config.log <<_ACEOF
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.11, which was
+It was created by sudo $as_me 1.9.11p1, which was
generated by GNU Autoconf 2.71. Invocation command line was
$ $0$ac_configure_args_raw
@@ -17821,8 +17821,8 @@ fi
*-*-linux*|*-*-k*bsd*-gnu)
shadow_funcs="getspnam"
test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
- # Check for SECCOMP_SET_MODE_FILTER in linux/seccomp.h
- ac_fn_check_decl "$LINENO" "SECCOMP_SET_MODE_FILTER" "ac_cv_have_decl_SECCOMP_SET_MODE_FILTER" "
+ # Check for SECCOMP_MODE_FILTER in linux/seccomp.h
+ ac_fn_check_decl "$LINENO" "SECCOMP_MODE_FILTER" "ac_cv_have_decl_SECCOMP_MODE_FILTER" "
#include <sys/types.h>
#include <sys/prctl.h>
#include <asm/unistd.h>
@@ -17830,13 +17830,13 @@ fi
#include <linux/filter.h>
" "$ac_c_undeclared_builtin_options" "CFLAGS"
-if test "x$ac_cv_have_decl_SECCOMP_SET_MODE_FILTER" = xyes
+if test "x$ac_cv_have_decl_SECCOMP_MODE_FILTER" = xyes
then :
ac_have_decl=1
else $as_nop
ac_have_decl=0
fi
-printf "%s\n" "#define HAVE_DECL_SECCOMP_SET_MODE_FILTER $ac_have_decl" >>confdefs.h
+printf "%s\n" "#define HAVE_DECL_SECCOMP_MODE_FILTER $ac_have_decl" >>confdefs.h
# We call getrandom via syscall(3) in case it is not in libc
ac_fn_c_check_header_compile "$LINENO" "linux/random.h" "ac_cv_header_linux_random_h" "$ac_includes_default"
@@ -33050,7 +33050,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# 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.11, which was
+This file was extended by sudo $as_me 1.9.11p1, which was
generated by GNU Autoconf 2.71. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -33118,7 +33118,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config='$ac_cs_config_escaped'
ac_cs_version="\\
-sudo config.status 1.9.11
+sudo config.status 1.9.11p1
configured by $0, generated by GNU Autoconf 2.71,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 4d4278f81..fc4abf8a5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -18,7 +18,7 @@ dnl ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
dnl
AC_PREREQ([2.70])
-AC_INIT([sudo], [1.9.11], [https://bugzilla.sudo.ws/], [sudo])
+AC_INIT([sudo], [1.9.11p1], [https://bugzilla.sudo.ws/], [sudo])
AC_CONFIG_HEADERS([config.h pathnames.h])
AC_CONFIG_SRCDIR([src/sudo.c])
AC_CONFIG_AUX_DIR([scripts])
@@ -2065,8 +2065,8 @@ case "$host" in
*-*-linux*|*-*-k*bsd*-gnu)
shadow_funcs="getspnam"
test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
- # Check for SECCOMP_SET_MODE_FILTER in linux/seccomp.h
- AC_CHECK_DECLS([SECCOMP_SET_MODE_FILTER], [], [], [
+ # Check for SECCOMP_MODE_FILTER in linux/seccomp.h
+ AC_CHECK_DECLS([SECCOMP_MODE_FILTER], [], [], [
#include <sys/types.h>
#include <sys/prctl.h>
#include <asm/unistd.h>
diff --git a/docs/sudoers.man.in b/docs/sudoers.man.in
index e12462665..5f73f7ca2 100644
--- a/docs/sudoers.man.in
+++ b/docs/sudoers.man.in
@@ -1273,7 +1273,7 @@ User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \e
Cmnd_Spec_List ::= Cmnd_Spec |
Cmnd_Spec ',' Cmnd_Spec_List
-Cmnd_Spec ::= Runas_Spec? Option_Spec* Tag_Spec* Cmnd
+Cmnd_Spec ::= Runas_Spec? Option_Spec* (Tag_Spec ':')* Cmnd
Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
@@ -1304,11 +1304,11 @@ Chdir_Spec ::= 'CWD=directory'
Chroot_Spec ::= 'CHROOT=directory'
-Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
- 'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
- 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'INTERCEPT:' |
- 'NOINTERCEPT:' | 'PASSWD:' | 'NOPASSWD:' | 'SETENV:' |
- 'NOSETENV:')
+Tag_Spec ::= ('EXEC' | 'NOEXEC' | 'FOLLOW' | 'NOFOLLOW' |
+ 'LOG_INPUT' | 'NOLOG_INPUT' | 'LOG_OUTPUT' |
+ 'NOLOG_OUTPUT' | 'MAIL' | 'NOMAIL' | 'INTERCEPT' |
+ 'NOINTERCEPT' | 'PASSWD' | 'NOPASSWD' | 'SETENV' |
+ 'NOSETENV')
.RE
.fi
.PP
diff --git a/docs/sudoers.mdoc.in b/docs/sudoers.mdoc.in
index 9211fbe9e..29aeacfdd 100644
--- a/docs/sudoers.mdoc.in
+++ b/docs/sudoers.mdoc.in
@@ -1223,7 +1223,7 @@ User_Spec ::= User_List Host_List '=' Cmnd_Spec_List \e
Cmnd_Spec_List ::= Cmnd_Spec |
Cmnd_Spec ',' Cmnd_Spec_List
-Cmnd_Spec ::= Runas_Spec? Option_Spec* Tag_Spec* Cmnd
+Cmnd_Spec ::= Runas_Spec? Option_Spec* (Tag_Spec ':')* Cmnd
Runas_Spec ::= '(' Runas_List? (':' Runas_List)? ')'
@@ -1262,11 +1262,11 @@ Chdir_Spec ::= 'CWD=directory'
Chroot_Spec ::= 'CHROOT=directory'
-Tag_Spec ::= ('EXEC:' | 'NOEXEC:' | 'FOLLOW:' | 'NOFOLLOW' |
- 'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' |
- 'NOLOG_OUTPUT:' | 'MAIL:' | 'NOMAIL:' | 'INTERCEPT:' |
- 'NOINTERCEPT:' | 'PASSWD:' | 'NOPASSWD:' | 'SETENV:' |
- 'NOSETENV:')
+Tag_Spec ::= ('EXEC' | 'NOEXEC' | 'FOLLOW' | 'NOFOLLOW' |
+ 'LOG_INPUT' | 'NOLOG_INPUT' | 'LOG_OUTPUT' |
+ 'NOLOG_OUTPUT' | 'MAIL' | 'NOMAIL' | 'INTERCEPT' |
+ 'NOINTERCEPT' | 'PASSWD' | 'NOPASSWD' | 'SETENV' |
+ 'NOSETENV')
.Ed
.Pp
A
diff --git a/include/sudo_event.h b/include/sudo_event.h
index 2bb7bb2be..12bb89478 100644
--- a/include/sudo_event.h
+++ b/include/sudo_event.h
@@ -102,10 +102,10 @@ struct sudo_event_base {
int pfd_high; /* highest slot used */
int pfd_free; /* idx of next free entry or pfd_max if full */
#else
- fd_set *readfds_in; /* read I/O descriptor set (in) */
- fd_set *writefds_in; /* write I/O descriptor set (in) */
- fd_set *readfds_out; /* read I/O descriptor set (out) */
- fd_set *writefds_out; /* write I/O descriptor set (out) */
+ void *readfds_in; /* read I/O descriptor set (in) */
+ void *writefds_in; /* write I/O descriptor set (in) */
+ void *readfds_out; /* read I/O descriptor set (out) */
+ void *writefds_out; /* write I/O descriptor set (out) */
int maxfd; /* max fd we can store in readfds/writefds */
int highfd; /* highest fd to pass as 1st arg to select */
#endif /* HAVE_POLL */
diff --git a/lib/protobuf-c/protobuf-c.c b/lib/protobuf-c/protobuf-c.c
index 96b750650..9d56e1fec 100644
--- a/lib/protobuf-c/protobuf-c.c
+++ b/lib/protobuf-c/protobuf-c.c
@@ -331,9 +331,8 @@ int32_size(int32_t v)
static inline uint32_t
zigzag32(int32_t v)
{
- // Note: the right-shift must be arithmetic
- // Note: left shift must be unsigned because of overflow
- return ((uint32_t)(v) << 1) ^ (uint32_t)(v >> 31);
+ // Note: Using unsigned types prevents undefined behavior
+ return ((uint32_t)v << 1) ^ -((uint32_t)v >> 31);
}
/**
@@ -395,9 +394,8 @@ uint64_size(uint64_t v)
static inline uint64_t
zigzag64(int64_t v)
{
- // Note: the right-shift must be arithmetic
- // Note: left shift must be unsigned because of overflow
- return ((uint64_t)(v) << 1) ^ (uint64_t)(v >> 63);
+ // Note: Using unsigned types prevents undefined behavior
+ return ((uint64_t)v << 1) ^ -((uint64_t)v >> 63);
}
/**
@@ -817,7 +815,8 @@ uint32_pack(uint32_t value, uint8_t *out)
}
/**
- * Pack a signed 32-bit integer and return the number of bytes written.
+ * Pack a signed 32-bit integer and return the number of bytes written,
+ * passed as unsigned to avoid implementation-specific behavior.
* Negative numbers are encoded as two's complement 64-bit integers.
*
* \param value
@@ -828,14 +827,14 @@ uint32_pack(uint32_t value, uint8_t *out)
* Number of bytes written to `out`.
*/
static inline size_t
-int32_pack(int32_t value, uint8_t *out)
+int32_pack(uint32_t value, uint8_t *out)
{
- if (value < 0) {
+ if ((int32_t)value < 0) {
out[0] = value | 0x80;
out[1] = (value >> 7) | 0x80;
out[2] = (value >> 14) | 0x80;
out[3] = (value >> 21) | 0x80;
- out[4] = (value >> 28) | 0x80;
+ out[4] = (value >> 28) | 0xf0;
out[5] = out[6] = out[7] = out[8] = 0xff;
out[9] = 0x01;
return 10;
@@ -2440,7 +2439,7 @@ static inline int32_t
unzigzag32(uint32_t v)
{
// Note: Using unsigned types prevents undefined behavior
- return (int32_t)((v >> 1) ^ (~(v & 1) + 1));
+ return (int32_t)((v >> 1) ^ -(v & 1));
}
static inline uint32_t
@@ -2482,7 +2481,7 @@ static inline int64_t
unzigzag64(uint64_t v)
{
// Note: Using unsigned types prevents undefined behavior
- return (int64_t)((v >> 1) ^ (~(v & 1) + 1));
+ return (int64_t)((v >> 1) ^ -(v & 1));
}
static inline uint64_t
@@ -2619,11 +2618,14 @@ parse_required_member(ScannedMember *scanned_member,
return FALSE;
def_mess = scanned_member->field->default_value;
- subm = protobuf_c_message_unpack(scanned_member->field->descriptor,
- allocator,
- len - pref_len,
- data + pref_len);
-
+ if (len > pref_len) {
+ subm = protobuf_c_message_unpack(scanned_member->field->descriptor,
+ allocator,
+ len - pref_len,
+ data + pref_len);
+ } else {
+ subm = NULL;
+ }
if (maybe_clear &&
*pmessage != NULL &&
*pmessage != def_mess)
@@ -3553,7 +3555,7 @@ protobuf_c_service_generated_init(ProtobufCService *service,
service->descriptor = descriptor;
service->destroy = destroy;
service->invoke = protobuf_c_service_invoke_internal;
- memset(service + 1, 0, descriptor->n_methods * sizeof(GenericHandler));
+ memset(&service[1], 0, descriptor->n_methods * sizeof(GenericHandler));
}
void protobuf_c_service_destroy(ProtobufCService *service)
diff --git a/lib/util/event_select.c b/lib/util/event_select.c
index a2ee9d1b3..8d3e8a9b2 100644
--- a/lib/util/event_select.c
+++ b/lib/util/event_select.c
@@ -120,12 +120,12 @@ sudo_ev_add_impl(struct sudo_event_base *base, struct sudo_event *ev)
if (ISSET(ev->events, SUDO_EV_READ)) {
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: added fd %d to readfs",
__func__, ev->fd);
- FD_SET(ev->fd, base->readfds_in);
+ FD_SET(ev->fd, (fd_set *)base->readfds_in);
}
if (ISSET(ev->events, SUDO_EV_WRITE)) {
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: added fd %d to writefds",
__func__, ev->fd);
- FD_SET(ev->fd, base->writefds_in);
+ FD_SET(ev->fd, (fd_set *)base->writefds_in);
}
if (ev->fd > base->highfd)
base->highfd = ev->fd;
@@ -142,17 +142,17 @@ sudo_ev_del_impl(struct sudo_event_base *base, struct sudo_event *ev)
if (ISSET(ev->events, SUDO_EV_READ)) {
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: removed fd %d from readfds",
__func__, ev->fd);
- FD_CLR(ev->fd, base->readfds_in);
+ FD_CLR(ev->fd, (fd_set *)base->readfds_in);
}
if (ISSET(ev->events, SUDO_EV_WRITE)) {
sudo_debug_printf(SUDO_DEBUG_DEBUG, "%s: removed fd %d from writefds",
__func__, ev->fd);
- FD_CLR(ev->fd, base->writefds_in);
+ FD_CLR(ev->fd, (fd_set *)base->writefds_in);
}
if (base->highfd == ev->fd) {
for (;;) {
- if (FD_ISSET(base->highfd, base->readfds_in) ||
- FD_ISSET(base->highfd, base->writefds_in))
+ if (FD_ISSET(base->highfd, (fd_set *)base->readfds_in) ||
+ FD_ISSET(base->highfd, (fd_set *)base->writefds_in))
break;
if (--base->highfd < 0)
break;
@@ -230,9 +230,9 @@ sudo_ev_scan_impl(struct sudo_event_base *base, int flags)
TAILQ_FOREACH(ev, &base->events, entries) {
if (ev->fd >= 0) {
int what = 0;
- if (FD_ISSET(ev->fd, base->readfds_out))
+ if (FD_ISSET(ev->fd, (fd_set *)base->readfds_out))
what |= (ev->events & SUDO_EV_READ);
- if (FD_ISSET(ev->fd, base->writefds_out))
+ if (FD_ISSET(ev->fd, (fd_set *)base->writefds_out))
what |= (ev->events & SUDO_EV_WRITE);
if (what != 0) {
/* Make event active. */
diff --git a/logsrvd/logsrvd.c b/logsrvd/logsrvd.c
index 4eba07e07..4bf739ff5 100644
--- a/logsrvd/logsrvd.c
+++ b/logsrvd/logsrvd.c
@@ -929,6 +929,8 @@ server_msg_cb(int fd, int what, void *v)
}
if (nwritten == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ debug_return;
sudo_warn("%s: write", closure->ipaddr);
goto finished;
}
@@ -1043,7 +1045,7 @@ client_msg_cb(int fd, int what, void *v)
__func__, nread, closure->ipaddr);
switch (nread) {
case -1:
- if (errno == EAGAIN)
+ if (errno == EAGAIN || errno == EINTR)
debug_return;
sudo_warn("%s: read", closure->ipaddr);
goto close_connection;
@@ -1519,9 +1521,10 @@ listener_cb(int fd, int what, void *v)
"unable to start new connection");
}
} else {
- if (errno != EAGAIN)
- sudo_warn("accept");
+ if (errno == EAGAIN || errno == EINTR)
+ debug_return;
/* TODO: pause accepting on ENFILE and EMFILE */
+ sudo_warn("accept");
}
debug_return;
diff --git a/logsrvd/logsrvd_relay.c b/logsrvd/logsrvd_relay.c
index f23b88f90..6937ed82c 100644
--- a/logsrvd/logsrvd_relay.c
+++ b/logsrvd/logsrvd_relay.c
@@ -799,7 +799,7 @@ relay_server_msg_cb(int fd, int what, void *v)
relay_closure->relay_name.name, relay_closure->relay_name.ipaddr);
switch (nread) {
case -1:
- if (errno == EAGAIN)
+ if (errno == EAGAIN || errno == EINTR)
debug_return;
sudo_warn("%s: read", relay_closure->relay_name.ipaddr);
closure->errstr = _("unable to read from relay");
@@ -970,6 +970,8 @@ relay_client_msg_cb(int fd, int what, void *v)
{
nwritten = write(fd, buf->data + buf->off, buf->len - buf->off);
if (nwritten == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ debug_return;
sudo_warn("%s: write", relay_closure->relay_name.ipaddr);
closure->errstr = _("error writing to relay");
goto send_error;
diff --git a/logsrvd/sendlog.c b/logsrvd/sendlog.c
index 094bd369d..50d7f59c1 100644
--- a/logsrvd/sendlog.c
+++ b/logsrvd/sendlog.c
@@ -1359,7 +1359,7 @@ server_msg_cb(int fd, int what, void *v)
__func__, nread);
switch (nread) {
case -1:
- if (errno == EAGAIN)
+ if (errno == EAGAIN || errno == EINTR)
debug_return;
sudo_warn("recv");
goto bad;
@@ -1479,6 +1479,8 @@ client_msg_cb(int fd, int what, void *v)
nwritten = send(fd, buf->data + buf->off, buf->len - buf->off, 0);
}
if (nwritten == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+ debug_return;
sudo_warn("send");
goto bad;
}
diff --git a/plugins/sudoers/sudoers.in b/plugins/sudoers/sudoers.in
index a0d293409..5efda5d23 100644
--- a/plugins/sudoers/sudoers.in
+++ b/plugins/sudoers/sudoers.in
@@ -64,7 +64,7 @@
##
## Uncomment to enable logging of a command's output, except for
## sudoreplay and reboot. Use sudoreplay to play back logged sessions.
-## Sudo will create up to 2,176,782,336 I/O logs before recycing them.
+## Sudo will create up to 2,176,782,336 I/O logs before recycling them.
## Set maxseq to a smaller number if you don't have unlimited disk space.
# Defaults log_output
# Defaults!/usr/bin/sudoreplay !log_output
diff --git a/src/exec_ptrace.h b/src/exec_ptrace.h
index 7f26283a8..4a5a86581 100644
--- a/src/exec_ptrace.h
+++ b/src/exec_ptrace.h
@@ -76,6 +76,7 @@
# define reg_arg4(x) (x).r10
#elif defined(__aarch64__)
# define SECCOMP_AUDIT_ARCH AUDIT_ARCH_AARCH64
+# define sudo_pt_regs struct user_pt_regs
# define reg_syscall(x) (x).regs[8] /* w8 */
# define reg_retval(x) (x).regs[0] /* x0 */
# define reg_sp(x) (x).sp /* sp */
diff --git a/src/exec_pty.c b/src/exec_pty.c
index 326d8318a..e2fd9c60e 100644
--- a/src/exec_pty.c
+++ b/src/exec_pty.c
@@ -676,9 +676,11 @@ read_callback(int fd, int what, void *v)
/* Schedule SIGTTIN to be forwarded to the command. */
schedule_signal(iob->ec, SIGTTIN);
}
- if (errno == EAGAIN || errno == EINTR)
+ if (errno == EAGAIN || errno == EINTR) {
+ /* Not an error, retry later. */
break;
- /* treat read error as fatal and close the fd */
+ }
+ /* Treat read error as fatal and close the fd. */
sudo_debug_printf(SUDO_DEBUG_ERROR,
"error reading fd %d: %s", fd, strerror(errno));
FALLTHROUGH;
@@ -705,18 +707,18 @@ read_callback(int fd, int what, void *v)
iob->ec->cmnd_pid = -1;
}
iob->len += n;
- /* Enable writer now that there is data in the buffer. */
+ /* Disable reader if buffer is full. */
+ if (iob->len == sizeof(iob->buf))
+ sudo_ev_del(evbase, iob->revent);
+ /* Enable writer now that there is new data in the buffer. */
if (iob->wevent != NULL) {
if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
sudo_fatal("%s", U_("unable to add event to queue"));
}
- /* Re-enable reader if buffer is not full. */
- if (iob->len != sizeof(iob->buf)) {
- if (sudo_ev_add(evbase, iob->revent, NULL, false) == -1)
- sudo_fatal("%s", U_("unable to add event to queue"));
- }
break;
}
+
+ debug_return;
}
/*
@@ -783,7 +785,7 @@ write_callback(int fd, int what, void *v)
}
FALLTHROUGH;
case EAGAIN:
- /* not an error */
+ /* Not an error, retry later. */
break;
default:
/* XXX - need a way to distinguish non-exec error. */
@@ -798,20 +800,16 @@ write_callback(int fd, int what, void *v)
sudo_debug_printf(SUDO_DEBUG_INFO,
"wrote %zd bytes to fd %d", n, fd);
iob->off += n;
- /* Reset buffer if fully consumed. */
+ /* Disable writer and reset the buffer if fully consumed. */
if (iob->off == iob->len) {
iob->off = iob->len = 0;
+ sudo_ev_del(evbase, iob->wevent);
/* Forward the EOF from reader to writer. */
if (iob->revent == NULL) {
safe_close(fd);
ev_free_by_fd(evbase, fd);
}
}
- /* Re-enable writer if buffer is not empty. */
- if (iob->len > iob->off) {
- if (sudo_ev_add(evbase, iob->wevent, NULL, false) == -1)
- sudo_fatal("%s", U_("unable to add event to queue"));
- }
/* Enable reader if buffer is not full. */
if (iob->revent != NULL &&
(ttymode == TERM_RAW || !USERTTY_EVENT(iob->revent))) {
@@ -821,6 +819,8 @@ write_callback(int fd, int what, void *v)
}
}
}
+
+ debug_return;
}
static void
@@ -844,8 +844,10 @@ io_buf_new(int rfd, int wfd,
if ((iob = malloc(sizeof(*iob))) == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
iob->ec = ec;
- iob->revent = sudo_ev_alloc(rfd, SUDO_EV_READ, read_callback, iob);
- iob->wevent = sudo_ev_alloc(wfd, SUDO_EV_WRITE, write_callback, iob);
+ iob->revent = sudo_ev_alloc(rfd, SUDO_EV_READ|SUDO_EV_PERSIST,
+ read_callback, iob);
+ iob->wevent = sudo_ev_alloc(wfd, SUDO_EV_WRITE|SUDO_EV_PERSIST,
+ write_callback, iob);
iob->len = 0;
iob->off = 0;
iob->action = action;
diff --git a/src/sudo_exec.h b/src/sudo_exec.h
index d225524d5..2f099a332 100644
--- a/src/sudo_exec.h
+++ b/src/sudo_exec.h
@@ -95,13 +95,13 @@ union sudo_token_un {
* On MIPS we can't change the syscall return and only support log_subcmds.
*/
#if defined(_PATH_SUDO_INTERCEPT) && defined(__linux__)
-# if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER
+# if defined(HAVE_DECL_SECCOMP_MODE_FILTER) && HAVE_DECL_SECCOMP_MODE_FILTER
# if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__) || defined(__arm__) || defined(__mips__) || defined(__powerpc__) || (defined(__riscv) && __riscv_xlen == 64) || defined(__s390__)
# ifndef HAVE_PTRACE_INTERCEPT
# define HAVE_PTRACE_INTERCEPT 1
# endif /* HAVE_PTRACE_INTERCEPT */
# endif /* __amd64__ || __i386__ || __aarch64__ || __riscv || __s390__ */
-# endif /* HAVE_DECL_SECCOMP_SET_MODE_FILTER */
+# endif /* HAVE_DECL_SECCOMP_MODE_FILTER */
#endif /* _PATH_SUDO_INTERCEPT && __linux__ */
/*
diff --git a/src/sudo_noexec.c b/src/sudo_noexec.c
index 3a2abdfdd..fd8117226 100644
--- a/src/sudo_noexec.c
+++ b/src/sudo_noexec.c
@@ -25,7 +25,7 @@
#include <sys/types.h>
-#if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER
+#if defined(HAVE_DECL_SECCOMP_MODE_FILTER) && HAVE_DECL_SECCOMP_MODE_FILTER
# include <sys/prctl.h>
# include <asm/unistd.h>
# include <linux/filter.h>
@@ -213,7 +213,7 @@ INTERPOSE(wordexp)
/*
* On Linux we can use a seccomp() filter to disable exec.
*/
-#if defined(HAVE_DECL_SECCOMP_SET_MODE_FILTER) && HAVE_DECL_SECCOMP_SET_MODE_FILTER
+#if defined(HAVE_DECL_SECCOMP_MODE_FILTER) && HAVE_DECL_SECCOMP_MODE_FILTER
/* Older systems may not support execveat(2). */
#ifndef __NR_execveat
@@ -248,4 +248,4 @@ noexec_ctor(void)
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == 0)
(void)prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &exec_fprog);
}
-#endif /* HAVE_DECL_SECCOMP_SET_MODE_FILTER */
+#endif /* HAVE_DECL_SECCOMP_MODE_FILTER */