This patch will upgrade Sudo version 1.9.11 to Sudo version 1.9.11 patchlevel 1. To apply: $ cd sudo-1.9.11 $ patch -p1 < sudo-1.9.11p1.patch diff -urNa sudo-1.9.11/ChangeLog sudo-1.9.11p1/ChangeLog --- sudo-1.9.11/ChangeLog Mon Jun 6 08:43:00 2022 +++ sudo-1.9.11p1/ChangeLog Wed Jun 8 08:34:21 2022 @@ -1,8 +1,126 @@ +2022-06-08 Todd C. Miller + + * .hgtags: + Added tag SUDO_1_9_11p1 for changeset 06b0f12fe91c + [feb8ae553833] [tip] <1.9> + + * NEWS, config.h.in, configure, configure.ac: + Merge sudo 1.9.11p1 from tip. + [06b0f12fe91c] [SUDO_1_9_11p1] <1.9> + + * NEWS, configure, configure.ac: + Sudo 1.9.11p1 + [7fcfdaacb15e] + +2022-06-07 Todd C. Miller + + * src/exec_pty.c: + Make read and write events persistent and disable as needed. For the + read callback, disable reader when the buffer is full. For the write + callback, disable writer when the buffer is consumed. + [2b6953dc4224] + + * config.h.in, configure, configure.ac, src/sudo_exec.h, + src/sudo_noexec.c: + Check for SECCOMP_MODE_FILTER not SECCOMP_SET_MODE_FILTER. This + matches the actual prctl() call we use. + [4222768293d1] + + * Merge pull request #157 from 0x2b3bfa0/improve-tag-spec-ebnf-docs + + Improve Tag_Spec EBNF documentation + [f528335aded5] + + * logsrvd/logsrvd.c, logsrvd/logsrvd_relay.c, logsrvd/sendlog.c: + Treat EINTR in a callback like we do EAGAIN. We shouldn't get EINTR + in practice since we set SA_RESTART when registering signal handlers + but it doesn't hurt to be consistent. + [acf3394e2df2] + + * Merge pull request #156 from delroth/aarch64-build + + exec_ptrace: fix missing sudo_pt_regs on aarch64 + [a7062c609a96] + +2022-06-07 Pierre Bourdon + + * src/exec_ptrace.h: + exec_ptrace: fix missing sudo_pt_regs on aarch64 + + AArch64 already had an existing "user_pt_regs" struct and didn't + need a struct alias before the renaming to "sudo_pt_regs". Make the + code build again by adding the now missing alias. + + Fixes: 2eb8ff17 + [3b55f40e9b83] + +2022-06-07 Helio Machado <0x2b3bfa0+git@googlemail.com> + + * docs/sudoers.man.in, docs/sudoers.mdoc.in: + Improve Tag_Spec EBNF documentation + [7e23ec31d124] + +2022-06-07 Todd C. Miller + + * Merge pull request #154 from 0x2b3bfa0/fix-tag-spec-docs + + Add missing colon in Tag_Spec documentation + [ec8f4610b677] + + * Merge pull request #152 from particleflux/fix-sudoers-typo + + Fix typo in sudoers comment + [bbbcff4c14ba] + +2022-06-07 Helio Machado <0x2b3bfa0+git@googlemail.com> + + * docs/sudoers.man.in, docs/sudoers.mdoc.in: + Add missing colon in Tag_Spec documentation + [e6f4c612e22a] + +2022-06-07 Stefan Linke + + * plugins/sudoers/sudoers.in: + Fix typo in sudoers comment + + Fix a typo in the sudoers comment about `maxseq` param. + + Introduced by 906eb19ece47023c659b4b3db2e7a6bb57dff0d9 in 1.9.11. + [b38fae41b3eb] + 2022-06-06 Todd C. Miller + * lib/protobuf-c/protobuf-c.c: + Only shift unsigned values to avoid implementation-specific + behavior. This converts the arithmetic shifts to logical shifts. + [e25aa8e9891a] + + * lib/protobuf-c/protobuf-c.c: + Fix issue protobuf-c#499: unsigned integer overflow Signed-off-by: + 10054172 + [f3637be4df4f] + + * include/sudo_event.h, lib/util/event_select.c: + Fix building with select (not poll) when fd_set is not defined in + sys/types.h. We can use a void * for the fd_set arrays and just add + a cast when using the FD_SET macros. + [5c636cbc11f0] + + * src/exec_pty.c: + Reinstall the event handler if we get EAGAIN from read/write + callback. The read and write events do not set SUDO_EV_PERSIST so we + need to explicitly re-enable the event if there is still data to be + read. Bug #963. + [0006cb6531f4] + + * logsrvd/logsrvd.c, logsrvd/logsrvd_relay.c, logsrvd/sendlog.c: + If write(2) returns EAGAIN just re-enter the event loop. This is + consistent with how we handle EAGAIN for read(2). + [e6478d917a0f] + * .hgtags: Added tag SUDO_1_9_11 for changeset d495c99554f7 - [74c59bc5c323] [tip] <1.9> + [74c59bc5c323] <1.9> * NEWS, config.h.in, configure, configure.ac, include/sudo_compat.h, logsrvd/tls_init.c, plugins/sudoers/regress/fuzz/fuzz_policy.c: diff -urNa sudo-1.9.11/NEWS sudo-1.9.11p1/NEWS --- sudo-1.9.11/NEWS Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/NEWS Wed Jun 8 08:32:57 2022 @@ -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 -urNa sudo-1.9.11/config.h.in sudo-1.9.11p1/config.h.in --- sudo-1.9.11/config.h.in Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/config.h.in Wed Jun 8 08:32:57 2022 @@ -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 -urNa sudo-1.9.11/configure sudo-1.9.11p1/configure --- sudo-1.9.11/configure Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/configure Wed Jun 8 08:32:57 2022 @@ -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 . # @@ -621,8 +621,8 @@ # 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 @@ # 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 @@ 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 @@ 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 @@ 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 @@ *-*-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 #include #include @@ -17830,13 +17830,13 @@ #include " "$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 @@ # 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 @@ 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 -urNa sudo-1.9.11/configure.ac sudo-1.9.11p1/configure.ac --- sudo-1.9.11/configure.ac Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/configure.ac Wed Jun 8 08:32:57 2022 @@ -18,7 +18,7 @@ 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 @@ *-*-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 #include #include diff -urNa sudo-1.9.11/docs/sudoers.man.in sudo-1.9.11p1/docs/sudoers.man.in --- sudo-1.9.11/docs/sudoers.man.in Mon Jun 6 08:42:00 2022 +++ sudo-1.9.11p1/docs/sudoers.man.in Wed Jun 8 08:32:57 2022 @@ -1273,7 +1273,7 @@ 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 @@ 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 -urNa sudo-1.9.11/docs/sudoers.mdoc.in sudo-1.9.11p1/docs/sudoers.mdoc.in --- sudo-1.9.11/docs/sudoers.mdoc.in Mon Jun 6 08:42:00 2022 +++ sudo-1.9.11p1/docs/sudoers.mdoc.in Wed Jun 8 08:32:57 2022 @@ -1223,7 +1223,7 @@ 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 @@ 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 -urNa sudo-1.9.11/include/sudo_event.h sudo-1.9.11p1/include/sudo_event.h --- sudo-1.9.11/include/sudo_event.h Mon Jun 6 08:41:49 2022 +++ sudo-1.9.11p1/include/sudo_event.h Wed Jun 8 08:32:57 2022 @@ -102,10 +102,10 @@ 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 -urNa sudo-1.9.11/lib/protobuf-c/protobuf-c.c sudo-1.9.11p1/lib/protobuf-c/protobuf-c.c --- sudo-1.9.11/lib/protobuf-c/protobuf-c.c Mon Jun 6 08:42:00 2022 +++ sudo-1.9.11p1/lib/protobuf-c/protobuf-c.c Wed Jun 8 08:32:57 2022 @@ -331,9 +331,8 @@ 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 @@ 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 @@ } /** - * 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 @@ * 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 @@ 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 @@ 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 @@ 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 @@ 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 -urNa sudo-1.9.11/lib/util/event_select.c sudo-1.9.11p1/lib/util/event_select.c --- sudo-1.9.11/lib/util/event_select.c Mon Jun 6 08:41:49 2022 +++ sudo-1.9.11p1/lib/util/event_select.c Wed Jun 8 08:32:57 2022 @@ -120,12 +120,12 @@ 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 @@ 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 @@ 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 -urNa sudo-1.9.11/logsrvd/logsrvd.c sudo-1.9.11p1/logsrvd/logsrvd.c --- sudo-1.9.11/logsrvd/logsrvd.c Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/logsrvd/logsrvd.c Wed Jun 8 08:32:57 2022 @@ -929,6 +929,8 @@ } if (nwritten == -1) { + if (errno == EAGAIN || errno == EINTR) + debug_return; sudo_warn("%s: write", closure->ipaddr); goto finished; } @@ -1043,7 +1045,7 @@ __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 @@ "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 -urNa sudo-1.9.11/logsrvd/logsrvd_relay.c sudo-1.9.11p1/logsrvd/logsrvd_relay.c --- sudo-1.9.11/logsrvd/logsrvd_relay.c Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/logsrvd/logsrvd_relay.c Wed Jun 8 08:32:57 2022 @@ -799,7 +799,7 @@ 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 @@ { 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 -urNa sudo-1.9.11/logsrvd/sendlog.c sudo-1.9.11p1/logsrvd/sendlog.c --- sudo-1.9.11/logsrvd/sendlog.c Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/logsrvd/sendlog.c Wed Jun 8 08:32:57 2022 @@ -1359,7 +1359,7 @@ __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 @@ 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 -urNa sudo-1.9.11/plugins/sudoers/sudoers.in sudo-1.9.11p1/plugins/sudoers/sudoers.in --- sudo-1.9.11/plugins/sudoers/sudoers.in Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/plugins/sudoers/sudoers.in Wed Jun 8 08:32:57 2022 @@ -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 -urNa sudo-1.9.11/src/exec_ptrace.h sudo-1.9.11p1/src/exec_ptrace.h --- sudo-1.9.11/src/exec_ptrace.h Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/src/exec_ptrace.h Wed Jun 8 08:32:57 2022 @@ -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 -urNa sudo-1.9.11/src/exec_pty.c sudo-1.9.11p1/src/exec_pty.c --- sudo-1.9.11/src/exec_pty.c Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/src/exec_pty.c Wed Jun 8 08:32:57 2022 @@ -676,9 +676,11 @@ /* 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 @@ 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 @@ } 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 @@ 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 @@ } } } + + debug_return; } static void @@ -844,8 +844,10 @@ 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 -urNa sudo-1.9.11/src/sudo_exec.h sudo-1.9.11p1/src/sudo_exec.h --- sudo-1.9.11/src/sudo_exec.h Mon Jun 6 08:42:01 2022 +++ sudo-1.9.11p1/src/sudo_exec.h Wed Jun 8 08:32:57 2022 @@ -95,13 +95,13 @@ * 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 -urNa sudo-1.9.11/src/sudo_noexec.c sudo-1.9.11p1/src/sudo_noexec.c --- sudo-1.9.11/src/sudo_noexec.c Mon Jun 6 08:41:50 2022 +++ sudo-1.9.11p1/src/sudo_noexec.c Wed Jun 8 08:32:57 2022 @@ -25,7 +25,7 @@ #include -#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 # include # include @@ -213,7 +213,7 @@ /* * 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 @@ 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 */