diff -urNa sudo-1.9.5p1/ChangeLog sudo-1.9.5p2/ChangeLog --- sudo-1.9.5p1/ChangeLog Mon Jan 11 18:51:09 2021 +++ sudo-1.9.5p2/ChangeLog Sat Jan 23 08:46:58 2021 @@ -1,8 +1,143 @@ +2021-01-23 Todd C. Miller + + * .hgtags: + Added tag SUDO_1_9_5p2 for changeset 83685ffbc4df + [74a2ddc3e4a4] [tip] <1.9> + + * Merge sudo 1.9.5p2 from tip + [83685ffbc4df] [SUDO_1_9_5p2] <1.9> + + * plugins/sudoers/timestamp.c: + Fix the memset offset when converting a v1 timestamp to TS_LOCKEXCL. + We want to zero the struct starting at flags, not type (which was + just set). Found by Qualys. + [09f98816fc89] + + * src/parse_args.c: + Don't assume that argv is allocated as a single flat buffer. While + this is how the kernel behaves it is not a portable assumption. The + assumption may also be violated if getopt_long(3) permutes + arguments. Found by Qualys. + [c125fbe68783] + + * NEWS, configure, configure.ac: + Sudo 1.9.5p2 + [89a357d8da4e] + + * src/parse_args.c: + Reset valid_flags to MODE_NONINTERACTIVE for sudoedit. This is + consistent with how the -e option is handled. Also reject -H and -P + flags for sudoedit as was done in sudo 1.7. Found by Qualys, this is + part of the fix for CVE-2021-3156. + [9b97f1787804] + + * plugins/sudoers/policy.c: + Add sudoedit flag checks in plugin that are consistent with front- + end. Don't assume the sudo front-end is sending reasonable mode + flags. These checks need to be kept consistent between the sudo + front-end and the sudoers plugin. + [a97dc92eae6b] + + * plugins/sudoers/sudoers.c: + Fix potential buffer overflow when unescaping backslashes in + user_args. Also, do not try to unescaping backslashes unless in run + mode *and* we are running the command via a shell. Found by Qualys, + this fixes CVE-2021-3156. + [049ad90590be] + +2021-01-22 Fabrice Fontaine + + * lib/eventlog/Makefile.in: + lib/eventlog/Makefile.in: fix static build without closefrom + + Since version 1.9.4 and https://github.com/sudo- + project/sudo/commit/bd1ca79cca827a92e904f022e49df121931d4ff5, when + closefrom is not available, libsudo_eventlog.a depends on + libsudo_util.a. So reflect this dependency in the libtool file to + avoid the following static build failure of logsrvd: + + /bin/bash ../libtool --tag=disable-static --mode=link + /home/buildroot/autobuild/instance-1/output-1/host/bin/powerpc- + linux-gcc -o sudo_logsrvd logsrv_util.o iolog_writer.o logsrvd.o + logsrvd_conf.o -static -Wl,--enable-new-dtags -Wl,-z,relro + ../lib/iolog/libsudo_iolog.la ../lib/eventlog/libsudo_eventlog.la + ../lib/logsrv/liblogsrv.la /bin/bash ../libtool --tag=disable-static + --mode=link + /home/buildroot/autobuild/instance-1/output-1/host/bin/powerpc- + linux-gcc -o sudo_sendlog logsrv_util.o sendlog.o -static -Wl,-- + enable-new-dtags -Wl,-z,relro ../lib/iolog/libsudo_iolog.la + ../lib/eventlog/libsudo_eventlog.la ../lib/logsrv/liblogsrv.la + libtool: link: + /home/buildroot/autobuild/instance-1/output-1/host/bin/powerpc- + linux-gcc -o sudo_logsrvd logsrv_util.o iolog_writer.o logsrvd.o + logsrvd_conf.o -static -Wl,--enable-new-dtags -Wl,-z -Wl,relro + ../lib/iolog/.libs/libsudo_iolog.a /home/buildroot/autobuild/instanc + e-1/output-1/build/sudo-1.9.5p1/lib/util/.libs/libsudo_util.a + -lpthread -lz ../lib/eventlog/.libs/libsudo_eventlog.a + ../lib/logsrv/.libs/liblogsrv.a + /home/buildroot/autobuild/instance-1/output-1/host/opt/ext- + toolchain/bin/../lib/gcc/powerpc-buildroot-linux- + uclibc/8.3.0/../../../../powerpc-buildroot-linux-uclibc/bin/ld: + ../lib/eventlog/.libs/libsudo_eventlog.a(eventlog.o): in function + `send_mail.constprop.1': eventlog.c:(.text+0x149c): undefined + reference to `sudo_closefrom' collect2: error: ld returned 1 exit + status + + Fixes: + - http://autobuild.buildroot.org/results/515b45f876fa9de03c9235f86017f + 4dc10eb3b54 + + Signed-off-by: Fabrice Fontaine + [4e42d276c336] + +2021-01-21 Todd C. Miller + + * plugins/sudoers/log_client.c: + Do not add an unfinished write buffer to the queue if it is already + present. In client_msg_cb() we only remove a buffer from the queue + when it is finished. Inserting the buf again can cause a cycle in + the queue. + [b398dcc0933d] + +2021-01-20 Todd C. Miller + + * plugins/sudoers/log_client.c: + Fix problem when SSL_read() returns SSL_ERROR_WANT_WRITE. This can + happen when the socket cannot be written to immediately. We need to + set the read_instead_of_write flag in that case, _not_ + write_instead_of_read. Also sync comments with sendlog.c. Bug #954 + [e4239bb932aa] + +2021-01-18 Pavel Březina + + * plugins/sudoers/auth/pam.c: + pam: pass KRB5CCNAME to pam_authenticate environment if available + + If a PAM module wants to authenticate user using GSSAPI, the + authentication is broken if non-default ccache name is used in + KRB5CCNAME environment variable. + + One way to mitigate this would be to add this to env_keep, but this + also makes the variable available in the executed command which may + not be always desirable. + + This patch sets KRB5CCNAME for pam_authenticate only, if it is + available and not yet set. + [90aba6ba6e03] + +2021-01-15 Todd C. Miller + + * lib/util/progname.c: + Fix setprogname() emulation on systems without it. For fully- + qualified paths, store the string starting after the last slash, not + at the slash itself. + [111fde52d116] + 2021-01-11 Todd C. Miller * .hgtags: Added tag SUDO_1_9_5p1 for changeset 3a873a732416 - [e837c76279bc] [tip] <1.9> + [e837c76279bc] <1.9> * Merge sudo 1.9.5p1 from tip [3a873a732416] [SUDO_1_9_5p1] <1.9> diff -urNa sudo-1.9.5p1/NEWS sudo-1.9.5p2/NEWS --- sudo-1.9.5p1/NEWS Mon Jan 11 18:48:04 2021 +++ sudo-1.9.5p2/NEWS Sat Jan 23 08:45:11 2021 @@ -1,3 +1,31 @@ +What's new in Sudo 1.9.5p2 + + * Fixed sudo's setprogname(3) emulation on systems that don't + provide it. + + * Fixed a problem with the sudoers log server client where a partial + write to the server could result the sudo process consuming large + amounts of CPU time due to a cycle in the buffer queue. Bug #954. + + * Added a missing dependency on libsudo_util in libsudo_eventlog. + Fixes a link error when building sudo statically. + + * The user's KRB5CCNAME environment variable is now preserved when + performing PAM authentication. This fixes GSSAPI authentication + when the user has a non-default ccache. + + * When invoked as sudoedit, the same set of command line options + are now accepted as for "sudo -e". The -H and -P options are + now rejected for sudoedit and "sudo -e" which matches the sudo + 1.7 behavior. This is part of the fix for CVE-2021-3156. + + * Fixed a potential buffer overflow when unescaping backslashes + in the command's arguments. Normally, sudo escapes special + characters when running a command via a shell (sudo -s or sudo + -i). However, it was also possible to run sudoedit with the -s + or -i flags in which case no escaping had actually been done, + making a buffer overflow possible. This fixes CVE-2021-3156. + What's new in Sudo 1.9.5p1 * Fixed a regression introduced in sudo 1.9.5 where the editor run diff -urNa sudo-1.9.5p1/configure sudo-1.9.5p2/configure --- sudo-1.9.5p1/configure Mon Jan 11 18:48:04 2021 +++ sudo-1.9.5p2/configure Sat Jan 23 08:45:11 2021 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sudo 1.9.5p1. +# Generated by GNU Autoconf 2.69 for sudo 1.9.5p2. # # Report bugs to . # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='sudo' PACKAGE_TARNAME='sudo' -PACKAGE_VERSION='1.9.5p1' -PACKAGE_STRING='sudo 1.9.5p1' +PACKAGE_VERSION='1.9.5p2' +PACKAGE_STRING='sudo 1.9.5p2' PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/' PACKAGE_URL='' @@ -1584,7 +1584,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.5p1 to adapt to many kinds of systems. +\`configure' configures sudo 1.9.5p2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1650,7 +1650,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sudo 1.9.5p1:";; + short | recursive ) echo "Configuration of sudo 1.9.5p2:";; esac cat <<\_ACEOF @@ -1924,7 +1924,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sudo configure 1.9.5p1 +sudo configure 1.9.5p2 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2633,7 +2633,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.5p1, which was +It was created by sudo $as_me 1.9.5p2, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -28816,7 +28816,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.5p1, which was +This file was extended by sudo $as_me 1.9.5p2, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -28882,7 +28882,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sudo config.status 1.9.5p1 +sudo config.status 1.9.5p2 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urNa sudo-1.9.5p1/configure.ac sudo-1.9.5p2/configure.ac --- sudo-1.9.5p1/configure.ac Mon Jan 11 18:48:04 2021 +++ sudo-1.9.5p2/configure.ac Sat Jan 23 08:45:11 2021 @@ -18,7 +18,7 @@ dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. dnl AC_PREREQ([2.59]) -AC_INIT([sudo], [1.9.5p1], [https://bugzilla.sudo.ws/], [sudo]) +AC_INIT([sudo], [1.9.5p2], [https://bugzilla.sudo.ws/], [sudo]) AC_CONFIG_HEADERS([config.h pathnames.h]) AC_CONFIG_SRCDIR([src/sudo.c]) dnl diff -urNa sudo-1.9.5p1/lib/eventlog/Makefile.in sudo-1.9.5p2/lib/eventlog/Makefile.in --- sudo-1.9.5p1/lib/eventlog/Makefile.in Sat Jan 9 13:12:16 2021 +++ sudo-1.9.5p2/lib/eventlog/Makefile.in Sat Jan 23 08:45:11 2021 @@ -46,8 +46,9 @@ # Flags to pass to libtool LTFLAGS = @LT_STATIC@ -# Libraries for test programs -LIBS = $(top_builddir)/lib/util/libsudo_util.la +# Libraries +LT_LIBS = $(top_builddir)/lib/util/libsudo_util.la +LIBS = $(LT_LIBS) # Address sanitizer flags ASAN_CFLAGS = @ASAN_CFLAGS@ @@ -132,7 +133,7 @@ fi libsudo_eventlog.la: $(LIBEVENTLOG_OBJS) - $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LIBEVENTLOG_OBJS) + $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(LIBEVENTLOG_OBJS) $(LT_LIBS) check_wrap: $(CHECK_WRAP_OBJS) $(LIBUTIL) $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(CHECK_WRAP_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) diff -urNa sudo-1.9.5p1/lib/util/progname.c sudo-1.9.5p2/lib/util/progname.c --- sudo-1.9.5p1/lib/util/progname.c Sat Jan 9 13:12:16 2021 +++ sudo-1.9.5p2/lib/util/progname.c Sat Jan 23 08:45:11 2021 @@ -38,8 +38,8 @@ void sudo_setprogname(const char *name) { - const char *base = strrchr(name, '/'); - __progname = base ? base : name; + const char *slash = strrchr(name, '/'); + __progname = slash ? slash + 1 : name; } # endif @@ -123,8 +123,8 @@ void sudo_setprogname(const char *name) { - const char *base = strrchr(name, '/'); - progname = base ? base : name; + const char *slash = strrchr(name, '/'); + progname = slash ? slash + 1 : name; } #endif /* !HAVE_GETPROGNAME */ diff -urNa sudo-1.9.5p1/plugins/sudoers/auth/pam.c sudo-1.9.5p2/plugins/sudoers/auth/pam.c --- sudo-1.9.5p1/plugins/sudoers/auth/pam.c Sat Jan 9 13:12:16 2021 +++ sudo-1.9.5p2/plugins/sudoers/auth/pam.c Sat Jan 23 08:45:11 2021 @@ -114,10 +114,10 @@ /* * Messages from PAM account management when trusted mode is enabled: - * 1 Last successful login for %s: %s - * 2 Last successful login for %s: %s on %s - * 3 Last unsuccessful login for %s: %s - * 4 Last unsuccessful login for %s: %s on %s + * 1 Last successful login for %s: %s + * 2 Last successful login for %s: %s on %s + * 3 Last unsuccessful login for %s: %s + * 4 Last unsuccessful login for %s: %s on %s */ if ((catd = catopen("pam_comsec", NL_CAT_LOCALE)) != -1) { maxfilters += 4; @@ -288,6 +288,7 @@ int sudo_pam_verify(struct passwd *pw, char *prompt, sudo_auth *auth, struct sudo_conv_callback *callback) { + const char *envccname; const char *s; int *pam_status = (int *) auth->data; debug_decl(sudo_pam_verify, SUDOERS_DEBUG_AUTH); @@ -296,8 +297,27 @@ getpass_error = false; /* set by converse if user presses ^C */ conv_callback = callback; /* passed to conversation function */ + /* Set KRB5CCNAME from the user environment if not set to propagate this + * information to PAM modules that may use it to authentication. */ + envccname = sudo_getenv("KRB5CCNAME"); + if (envccname == NULL && user_ccname != NULL) { + if (sudo_setenv("KRB5CCNAME", user_ccname, true) != 0) { + sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, + "unable to set KRB5CCNAME"); + debug_return_int(AUTH_FAILURE); + } + } + /* PAM_SILENT prevents the authentication service from generating output. */ *pam_status = pam_authenticate(pamh, PAM_SILENT); + + /* Restore KRB5CCNAME to its original value. */ + if (envccname == NULL && sudo_unsetenv("KRB5CCNAME") != 0) { + sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, + "unable to restore KRB5CCNAME"); + debug_return_int(AUTH_FAILURE); + } + if (getpass_error) { /* error or ^C from tgetpass() */ debug_return_int(AUTH_INTR); diff -urNa sudo-1.9.5p1/plugins/sudoers/log_client.c sudo-1.9.5p2/plugins/sudoers/log_client.c --- sudo-1.9.5p1/plugins/sudoers/log_client.c Wed Dec 16 18:34:30 2020 +++ sudo-1.9.5p2/plugins/sudoers/log_client.c Sat Jan 23 08:45:11 2021 @@ -1700,7 +1700,8 @@ } closure->temporary_write_event = true; } - closure->write_instead_of_read = true; + /* Redirect write event to finish SSL_read() */ + closure->read_instead_of_write = true; debug_return; case SSL_ERROR_SSL: /* @@ -1842,6 +1843,7 @@ /* ssl wants to read, read event always active */ sudo_debug_printf(SUDO_DEBUG_NOTICE|SUDO_DEBUG_LINENO, "SSL_write returns SSL_ERROR_WANT_READ"); + /* Redirect read event to finish SSL_write() */ closure->write_instead_of_read = true; debug_return; case SSL_ERROR_WANT_WRITE: @@ -1888,9 +1890,6 @@ if (!client_message_completion(closure)) goto bad; } - } else { - /* not done yet */ - TAILQ_INSERT_HEAD(&closure->write_bufs, buf, entries); } debug_return; diff -urNa sudo-1.9.5p1/plugins/sudoers/policy.c sudo-1.9.5p2/plugins/sudoers/policy.c --- sudo-1.9.5p1/plugins/sudoers/policy.c Sat Jan 9 13:12:16 2021 +++ sudo-1.9.5p2/plugins/sudoers/policy.c Sat Jan 23 08:45:11 2021 @@ -88,10 +88,11 @@ int sudoers_policy_deserialize_info(void *v) { + const int edit_mask = MODE_EDIT|MODE_IGNORE_TICKET|MODE_NONINTERACTIVE; struct sudoers_open_info *info = v; - char * const *cur; const char *p, *errstr, *groups = NULL; const char *remhost = NULL; + char * const *cur; int flags = 0; debug_decl(sudoers_policy_deserialize_info, SUDOERS_DEBUG_PLUGIN); @@ -346,6 +347,12 @@ continue; } #endif + } + + /* Sudo front-end should restrict mode flags for sudoedit. */ + if (ISSET(flags, MODE_EDIT) && (flags & edit_mask) != flags) { + sudo_warnx(U_("invalid mode flags from sudo front end: 0x%x"), flags); + goto bad; } user_gid = (gid_t)-1; diff -urNa sudo-1.9.5p1/plugins/sudoers/sudoers.c sudo-1.9.5p2/plugins/sudoers/sudoers.c --- sudo-1.9.5p1/plugins/sudoers/sudoers.c Sat Jan 9 13:12:16 2021 +++ sudo-1.9.5p2/plugins/sudoers/sudoers.c Sat Jan 23 08:45:11 2021 @@ -547,7 +547,7 @@ /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */ /* XXX - causes confusion when root is not listed in sudoers */ - if (sudo_mode & (MODE_RUN | MODE_EDIT) && prev_user != NULL) { + if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT) && prev_user != NULL) { if (user_uid == 0 && strcmp(prev_user, "root") != 0) { struct passwd *pw; @@ -932,8 +932,8 @@ if (user_cmnd == NULL) user_cmnd = NewArgv[0]; - if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { - if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) { + if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT|MODE_CHECK)) { + if (!ISSET(sudo_mode, MODE_EDIT)) { const char *runchroot = user_runchroot; if (runchroot == NULL && def_runchroot != NULL && strcmp(def_runchroot, "*") != 0) @@ -961,7 +961,8 @@ sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); debug_return_int(NOT_FOUND_ERROR); } - if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) { + if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL) && + ISSET(sudo_mode, MODE_RUN)) { /* * When running a command via a shell, the sudo front-end * escapes potential meta chars. We unescape non-spaces @@ -969,9 +970,21 @@ */ for (to = user_args, av = NewArgv + 1; (from = *av); av++) { while (*from) { - if (from[0] == '\\' && !isspace((unsigned char)from[1])) + if (from[0] == '\\' && from[1] != '\0' && + !isspace((unsigned char)from[1])) { from++; + } + if (size - (to - user_args) < 1) { + sudo_warnx(U_("internal error, %s overflow"), + __func__); + debug_return_int(NOT_FOUND_ERROR); + } *to++ = *from++; + } + if (size - (to - user_args) < 1) { + sudo_warnx(U_("internal error, %s overflow"), + __func__); + debug_return_int(NOT_FOUND_ERROR); } *to++ = ' '; } diff -urNa sudo-1.9.5p1/plugins/sudoers/timestamp.c sudo-1.9.5p2/plugins/sudoers/timestamp.c --- sudo-1.9.5p1/plugins/sudoers/timestamp.c Sat Jan 9 13:12:16 2021 +++ sudo-1.9.5p2/plugins/sudoers/timestamp.c Sat Jan 23 08:45:11 2021 @@ -643,8 +643,8 @@ if (entry.size == sizeof(struct timestamp_entry_v1)) { /* Old sudo record, convert it to TS_LOCKEXCL. */ entry.type = TS_LOCKEXCL; - memset((char *)&entry + offsetof(struct timestamp_entry, type), 0, - nread - offsetof(struct timestamp_entry, type)); + memset((char *)&entry + offsetof(struct timestamp_entry, flags), 0, + nread - offsetof(struct timestamp_entry, flags)); if (ts_write(cookie->fd, cookie->fname, &entry, 0) == -1) debug_return_bool(false); } else { diff -urNa sudo-1.9.5p1/src/parse_args.c sudo-1.9.5p2/src/parse_args.c --- sudo-1.9.5p1/src/parse_args.c Wed Dec 16 18:33:44 2020 +++ sudo-1.9.5p2/src/parse_args.c Sat Jan 23 08:45:11 2021 @@ -117,7 +117,10 @@ /* * Default flags allowed when running a command. */ -#define DEFAULT_VALID_FLAGS (MODE_BACKGROUND|MODE_PRESERVE_ENV|MODE_RESET_HOME|MODE_LOGIN_SHELL|MODE_NONINTERACTIVE|MODE_SHELL) +#define DEFAULT_VALID_FLAGS (MODE_BACKGROUND|MODE_PRESERVE_ENV|MODE_RESET_HOME|MODE_LOGIN_SHELL|MODE_NONINTERACTIVE|MODE_PRESERVE_GROUPS|MODE_SHELL) +#define EDIT_VALID_FLAGS MODE_NONINTERACTIVE +#define LIST_VALID_FLAGS (MODE_NONINTERACTIVE|MODE_LONG_LIST) +#define VALIDATE_VALID_FLAGS MODE_NONINTERACTIVE /* Option number for the --host long option due to ambiguity of the -h flag. */ #define OPT_HOSTNAME 256 @@ -262,6 +265,7 @@ progname = "sudoedit"; mode = MODE_EDIT; sudo_settings[ARG_SUDOEDIT].value = "true"; + valid_flags = EDIT_VALID_FLAGS; } /* Load local IP addresses and masks. */ @@ -365,7 +369,7 @@ usage_excl(); mode = MODE_EDIT; sudo_settings[ARG_SUDOEDIT].value = "true"; - valid_flags = MODE_NONINTERACTIVE; + valid_flags = EDIT_VALID_FLAGS; break; case 'g': assert(optarg != NULL); @@ -377,6 +381,7 @@ break; case 'H': sudo_settings[ARG_SET_HOME].value = "true"; + SET(flags, MODE_RESET_HOME); break; case 'h': if (optarg == NULL) { @@ -431,7 +436,7 @@ usage_excl(); } mode = MODE_LIST; - valid_flags = MODE_NONINTERACTIVE|MODE_LONG_LIST; + valid_flags = LIST_VALID_FLAGS; break; case 'n': SET(flags, MODE_NONINTERACTIVE); @@ -439,6 +444,7 @@ break; case 'P': sudo_settings[ARG_PRESERVE_GROUPS].value = "true"; + SET(flags, MODE_PRESERVE_GROUPS); break; case 'p': /* An empty prompt is allowed. */ @@ -505,7 +511,7 @@ if (mode && mode != MODE_VALIDATE) usage_excl(); mode = MODE_VALIDATE; - valid_flags = MODE_NONINTERACTIVE; + valid_flags = VALIDATE_VALID_FLAGS; break; case 'V': if (mode && mode != MODE_VERSION) @@ -533,7 +539,7 @@ if (!mode) { /* Defer -k mode setting until we know whether it is a flag or not */ if (sudo_settings[ARG_IGNORE_TICKET].value != NULL) { - if (argc == 0 && !(flags & (MODE_SHELL|MODE_LOGIN_SHELL))) { + if (argc == 0 && !ISSET(flags, MODE_SHELL|MODE_LOGIN_SHELL)) { mode = MODE_INVALIDATE; /* -k by itself */ sudo_settings[ARG_IGNORE_TICKET].value = NULL; valid_flags = 0; @@ -601,23 +607,23 @@ /* * For shell mode we need to rewrite argv */ - if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) { + if (ISSET(flags, MODE_SHELL|MODE_LOGIN_SHELL) && ISSET(mode, MODE_RUN)) { char **av, *cmnd = NULL; int ac = 1; if (argc != 0) { /* shell -c "command" */ char *src, *dst; - size_t cmnd_size = (size_t) (argv[argc - 1] - argv[0]) + - strlen(argv[argc - 1]) + 1; + size_t size = 0; - cmnd = dst = reallocarray(NULL, cmnd_size, 2); - if (cmnd == NULL) + for (av = argv; *av != NULL; av++) + size += strlen(*av) + 1; + if (size == 0 || (cmnd = reallocarray(NULL, size, 2)) == NULL) sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); if (!gc_add(GC_PTR, cmnd)) exit(EXIT_FAILURE); - for (av = argv; *av != NULL; av++) { + for (dst = cmnd, av = argv; *av != NULL; av++) { for (src = *av; *src != '\0'; src++) { /* quote potential meta characters */ if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-' && *src != '$')