diff options
author | Todd C. Miller <Todd.Miller@sudo.ws> | 2021-06-11 13:04:55 -0600 |
---|---|---|
committer | Todd C. Miller <Todd.Miller@sudo.ws> | 2021-06-11 13:04:55 -0600 |
commit | d78aec38f166ce7c36e9d3f784591ee5b462b1b9 (patch) | |
tree | 6289978f781e1c96c258d6d8f2c6ea3e192f3f95 | |
parent | 2f96f81ba88587b087bfd2e934824c2746a02590 (diff) | |
parent | 2f3f3774a5269644b90effe3a36ec13c2ae7c150 (diff) | |
download | sudo-d78aec38f166ce7c36e9d3f784591ee5b462b1b9.tar.gz |
Merge sudo 1.9.7p1 from tipSUDO_1_9_7p1
-rw-r--r-- | MANIFEST | 1 | ||||
-rw-r--r-- | NEWS | 27 | ||||
-rwxr-xr-x | configure | 57 | ||||
-rw-r--r-- | configure.ac | 31 | ||||
-rw-r--r-- | doc/sudoreplay.man.in | 18 | ||||
-rw-r--r-- | doc/sudoreplay.mdoc.in | 18 | ||||
-rw-r--r-- | include/compat/nss_dbdefs.h | 18 | ||||
-rw-r--r-- | lib/fuzzstub/fuzzstub.c | 2 | ||||
-rw-r--r-- | lib/iolog/Makefile.in | 8 | ||||
-rw-r--r-- | lib/iolog/hostcheck.c | 1 | ||||
-rw-r--r-- | lib/util/Makefile.in | 31 | ||||
-rw-r--r-- | lib/util/getgrouplist.c | 78 | ||||
-rw-r--r-- | lib/util/regress/getgrouplist/getgids.c | 81 | ||||
-rw-r--r-- | logsrvd/Makefile.in | 2 | ||||
-rw-r--r-- | logsrvd/logsrvd.c | 13 | ||||
-rw-r--r-- | logsrvd/logsrvd.h | 4 | ||||
-rw-r--r-- | plugins/audit_json/audit_json.c | 38 | ||||
-rw-r--r-- | plugins/sudoers/defaults.h | 2 | ||||
-rw-r--r-- | plugins/sudoers/log_client.c | 2 | ||||
-rw-r--r-- | plugins/sudoers/policy.c | 10 | ||||
-rw-r--r-- | scripts/ltmain.sh | 3 | ||||
-rwxr-xr-x | scripts/mkpkg | 8 | ||||
-rw-r--r-- | src/Makefile.in | 14 | ||||
-rw-r--r-- | src/load_plugins.c | 20 | ||||
-rw-r--r-- | src/sudo_edit.c | 10 | ||||
-rw-r--r-- | src/ttyname.c | 4 |
26 files changed, 325 insertions, 176 deletions
@@ -237,6 +237,7 @@ lib/util/regress/fnmatch/fnm_test.in lib/util/regress/fuzz/fuzz_sudo_conf.c lib/util/regress/fuzz/fuzz_sudo_conf.dict lib/util/regress/getdelim/getdelim_test.c +lib/util/regress/getgrouplist/getgids.c lib/util/regress/getgrouplist/getgrouplist_test.c lib/util/regress/glob/files lib/util/regress/glob/globtest.c @@ -1,3 +1,30 @@ +What's new in Sudo 1.9.7p1 + + * Fixed an SELinux sudoedit bug when the edited temporary file + could not be opened. The sesh helper would still be run even + when there are no temporary files available to install. + + * Fixed a compilation problem on FreeBSD. + + * The sudo_noexec.so file is now built as a module on all systems + other than macOS. This makes it possible to use other libtool + implementations such as slibtool. On macOS shared libraries and + modules are not interchangeable and the version of libtool shipped + with sudo must be used. + + * Fixed a few bugs in the getgrouplist() emulation on Solaris when + reading from the local group file. + + * Fixed a bug in sudo_logsrvd that prevented periodic relay server + connection retries from occurring in "store_first" mode. + + * Disabled the nss_search()-based getgrouplist() emulation on HP-UX + due to a crash when the group source is set to "compat" in + /etc/nsswitch.conf. This is probably due to a mismatch between + include/compat/nss_dbdefs.h and what HP-UX uses internally. On + HP-UX we now just cycle through groups the slow way using + getgrent(). Bug #978. + What's new in Sudo 1.9.7 * The "fuzz" Makefile target now runs all the fuzzers for 8192 @@ -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.7. +# Generated by GNU Autoconf 2.71 for sudo 1.9.7p1. # # 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.7' -PACKAGE_STRING='sudo 1.9.7' +PACKAGE_VERSION='1.9.7p1' +PACKAGE_STRING='sudo 1.9.7p1' PACKAGE_BUGREPORT='https://bugzilla.sudo.ws/' PACKAGE_URL='' @@ -808,6 +808,7 @@ LDAP SELINUX_USAGE BSDAUTH_USAGE DONT_LEAK_PATH_INFO +NOEXEC_MODULE CHECK_NOEXEC INSTALL_NOEXEC INSTALL_BACKUP @@ -1616,7 +1617,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.7 to adapt to many kinds of systems. +\`configure' configures sudo 1.9.7p1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1682,7 +1683,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sudo 1.9.7:";; + short | recursive ) echo "Configuration of sudo 1.9.7p1:";; esac cat <<\_ACEOF @@ -1966,7 +1967,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sudo configure 1.9.7 +sudo configure 1.9.7p1 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2623,7 +2624,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.7, which was +It was created by sudo $as_me 1.9.7p1, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3538,6 +3539,7 @@ ac_config_headers="$ac_config_headers config.h pathnames.h" + # # Begin initial values for man page substitution # @@ -3593,6 +3595,7 @@ devsearch="/dev/pts:/dev/vt:/dev/term:/dev/zcons:/dev/pty:/dev" INSTALL_BACKUP= INSTALL_NOEXEC= CHECK_NOEXEC= +NOEXEC_MODULE=-module exampledir='$(docdir)/examples' devdir='$(srcdir)' PROGS="sudo" @@ -16604,6 +16607,10 @@ done fi RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES" + # Build sudo_noexec.so as a shared library, not a module. + # On Darwin, modules and shared libraries are incompatible. + NOEXEC_MODULE= + # Mach monotonic timer that runs while sleeping ac_fn_c_check_func "$LINENO" "mach_continuous_time" "ac_cv_func_mach_continuous_time" if test "x$ac_cv_func_mach_continuous_time" = xyes @@ -19835,34 +19842,6 @@ fi else $as_nop - # HP-UX - ac_fn_c_check_func "$LINENO" "__nss_XbyY_buf_alloc" "ac_cv_func___nss_XbyY_buf_alloc" -if test "x$ac_cv_func___nss_XbyY_buf_alloc" = xyes -then : - - ac_fn_c_check_func "$LINENO" "__nss_initf_group" "ac_cv_func___nss_initf_group" -if test "x$ac_cv_func___nss_initf_group" = xyes -then : - - ac_fn_c_check_header_compile "$LINENO" "nss_dbdefs.h" "ac_cv_header_nss_dbdefs_h" "$ac_includes_default" -if test "x$ac_cv_header_nss_dbdefs_h" = xyes -then : - printf "%s\n" "#define HAVE_NSS_DBDEFS_H 1" >>confdefs.h - -fi - - printf "%s\n" "#define HAVE_NSS_SEARCH 1" >>confdefs.h - - printf "%s\n" "#define HAVE___NSS_XBYY_BUF_ALLOC 1" >>confdefs.h - - printf "%s\n" "#define HAVE___NSS_INITF_GROUP 1" >>confdefs.h - - -fi - - -fi - fi @@ -29244,6 +29223,10 @@ printf "%s\n" "$sudo_cv_var_fallthrough_attribute" >&6; } if test X"$enable_werror" = X"yes"; then CFLAGS="${CFLAGS} -Werror" fi + case "$host" in + # Avoid unwanted warnings on macOS + darwin*) CFLAGS="${CFLAGS} -Wno-deprecated-declarations";; + esac fi CROSS_COMPILING="$cross_compiling" @@ -29871,7 +29854,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.7, which was +This file was extended by sudo $as_me 1.9.7p1, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -29939,7 +29922,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.7 +sudo config.status 1.9.7p1 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 9ce8ff266..c87eeb7a2 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.7], [https://bugzilla.sudo.ws/], [sudo]) +AC_INIT([sudo], [1.9.7p1], [https://bugzilla.sudo.ws/], [sudo]) AC_CONFIG_HEADERS([config.h pathnames.h]) AC_CONFIG_SRCDIR([src/sudo.c]) AC_CONFIG_AUX_DIR([scripts]) @@ -76,6 +76,7 @@ AC_SUBST([sesh_file]) AC_SUBST([INSTALL_BACKUP]) AC_SUBST([INSTALL_NOEXEC]) AC_SUBST([CHECK_NOEXEC]) +AC_SUBST([NOEXEC_MODULE]) AC_SUBST([DONT_LEAK_PATH_INFO]) AC_SUBST([BSDAUTH_USAGE]) AC_SUBST([SELINUX_USAGE]) @@ -227,6 +228,7 @@ dnl INSTALL_BACKUP= INSTALL_NOEXEC= CHECK_NOEXEC= +NOEXEC_MODULE=-module exampledir='$(docdir)/examples' devdir='$(srcdir)' PROGS="sudo" @@ -2170,6 +2172,10 @@ case "$host" in fi RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES" + # Build sudo_noexec.so as a shared library, not a module. + # On Darwin, modules and shared libraries are incompatible. + NOEXEC_MODULE= + # Mach monotonic timer that runs while sleeping AC_CHECK_FUNCS([mach_continuous_time]) @@ -2547,15 +2553,16 @@ AC_CHECK_FUNCS([getgrouplist], [], [ ]) ]) ], [ - # HP-UX - AC_CHECK_FUNC([__nss_XbyY_buf_alloc], [ - AC_CHECK_FUNC([__nss_initf_group], [ - AC_CHECK_HEADERS([nss_dbdefs.h]) - AC_DEFINE([HAVE_NSS_SEARCH]) - AC_DEFINE([HAVE___NSS_XBYY_BUF_ALLOC]) - AC_DEFINE([HAVE___NSS_INITF_GROUP]) - ]) - ]) + dnl HP-UX support disabled until "group: compat" fixed + dnl # HP-UX + dnl AC_CHECK_FUNC([__nss_XbyY_buf_alloc], [ + dnl AC_CHECK_FUNC([__nss_initf_group], [ + dnl AC_CHECK_HEADERS([nss_dbdefs.h]) + dnl AC_DEFINE([HAVE_NSS_SEARCH]) + dnl AC_DEFINE([HAVE___NSS_XBYY_BUF_ALLOC]) + dnl AC_DEFINE([HAVE___NSS_INITF_GROUP]) + dnl ]) + dnl]) ]) ]) ;; @@ -4681,6 +4688,10 @@ if test -n "$GCC"; then if test X"$enable_werror" = X"yes"; then CFLAGS="${CFLAGS} -Werror" fi + case "$host" in + # Avoid unwanted warnings on macOS + darwin*) CFLAGS="${CFLAGS} -Wno-deprecated-declarations";; + esac fi dnl diff --git a/doc/sudoreplay.man.in b/doc/sudoreplay.man.in index 44015162f..43d432c86 100644 --- a/doc/sudoreplay.man.in +++ b/doc/sudoreplay.man.in @@ -16,7 +16,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.TH "SUDOREPLAY" "@mansectsu@" "May 18, 2020" "Sudo @PACKAGE_VERSION@" "System Manager's Manual" +.TH "SUDOREPLAY" "@mansectsu@" "May 26, 2021" "Sudo @PACKAGE_VERSION@" "System Manager's Manual" .nh .if n .ad l .SH "NAME" @@ -50,17 +50,11 @@ The \fIID\fR should either be a six character sequence of digits and upper case letters, e.g., -\fR0100A5\fR, -a pattern matching the -\fIiolog_file\fR -option in the -\fIsudoers\fR -file, or a path name. -Path names may be relative to the -\fIiolog_dir\fR -option in the -\fIsudoers\fR -file (unless overridden by the +\fR0100A5\fR +or a path name. +Path names may be relative to the I/O log directory +\fI@iolog_dir@\fR +(unless overridden by the \fB\-d\fR option) or fully qualified, beginning with a \(oq/\(cq diff --git a/doc/sudoreplay.mdoc.in b/doc/sudoreplay.mdoc.in index f7adfa8cb..cb7084d42 100644 --- a/doc/sudoreplay.mdoc.in +++ b/doc/sudoreplay.mdoc.in @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd May 18, 2020 +.Dd May 26, 2021 .Dt SUDOREPLAY @mansectsu@ .Os Sudo @PACKAGE_VERSION@ .Sh NAME @@ -48,17 +48,11 @@ The .Em ID should either be a six character sequence of digits and upper case letters, e.g., -.Li 0100A5 , -a pattern matching the -.Em iolog_file -option in the -.Em sudoers -file, or a path name. -Path names may be relative to the -.Em iolog_dir -option in the -.Em sudoers -file (unless overridden by the +.Li 0100A5 +or a path name. +Path names may be relative to the I/O log directory +.Pa @iolog_dir@ +(unless overridden by the .Fl d option) or fully qualified, beginning with a .Ql / diff --git a/include/compat/nss_dbdefs.h b/include/compat/nss_dbdefs.h index 849bba447..726beae98 100644 --- a/include/compat/nss_dbdefs.h +++ b/include/compat/nss_dbdefs.h @@ -35,7 +35,8 @@ typedef enum { NSS_SUCCESS, NSS_NOTFOUND, - NSS_UNAVAIL + NSS_UNAVAIL, + NSS_TRYAGAIN } nss_status_t; typedef struct nss_db_params { @@ -55,19 +56,20 @@ struct nss_groupsbymem { gid_t *gid_array; int maxgids; int force_slow_way; - int (*str2ent)(const char *, int, void *, char *, int); - nss_status_t (*process_cstr)(const char *, int, struct nss_groupsbymem *); + int (*str2ent)(const char *instr, int instr_len, void *ent, char *buffer, int buflen); + nss_status_t (*process_cstr)(const char *instr, int instr_len, struct nss_groupsbymem *); int numgids; }; typedef struct { void *result; /* group struct to fill in. */ char *buffer; /* string buffer for above */ - size_t buflen; /* string buffer size */ + int buflen; /* string buffer size */ } nss_XbyY_buf_t; +struct nss_db_state; typedef struct { - void *state; /* really struct nss_db_state * */ + struct nss_db_state *s; #ifdef NEED_HPUX_MUTEX lwp_mutex_t lock; #endif @@ -78,7 +80,7 @@ typedef struct { #else # define NSS_DB_ROOT_INIT { 0 } #endif -# define DEFINE_NSS_DB_ROOT(name) nss_db_root_t name = NSS_DB_ROOT_INIT +#define DEFINE_NSS_DB_ROOT(name) nss_db_root_t name = NSS_DB_ROOT_INIT /* Backend function to find all groups a user belongs to for initgroups(). */ #define NSS_DBOP_GROUP_BYMEMBER 6 @@ -101,8 +103,8 @@ typedef struct { #endif typedef void (*nss_db_initf_t)(nss_db_params_t *); -extern nss_status_t nss_search(nss_db_root_t *, nss_db_initf_t, int, void *); -extern nss_XbyY_buf_t *_nss_XbyY_buf_alloc(int, int); +extern nss_status_t nss_search(nss_db_root_t *, nss_db_initf_t, int search_fnum, void *search_args); +extern nss_XbyY_buf_t *_nss_XbyY_buf_alloc(int struct_size, int buffer_size); extern void _nss_XbyY_buf_free(nss_XbyY_buf_t *); #endif /* COMPAT_NSS_DBDEFS_H */ diff --git a/lib/fuzzstub/fuzzstub.c b/lib/fuzzstub/fuzzstub.c index 4ad42496d..1e88644fa 100644 --- a/lib/fuzzstub/fuzzstub.c +++ b/lib/fuzzstub/fuzzstub.c @@ -44,6 +44,8 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); +sudo_dso_public int main(int argc, char *argv[]); + /* * Simple driver for fuzzers built for LLVM libfuzzer. * This stub library allows fuzz targets to be built and run without diff --git a/lib/iolog/Makefile.in b/lib/iolog/Makefile.in index 1b35f8cf8..76e476955 100644 --- a/lib/iolog/Makefile.in +++ b/lib/iolog/Makefile.in @@ -85,7 +85,7 @@ LIBFUZZSTUB = $(top_builddir)/lib/fuzzstub/libsudo_fuzzstub.la LIB_FUZZING_ENGINE = @FUZZ_ENGINE@ FUZZ_PROGS = fuzz_iolog_json fuzz_iolog_legacy fuzz_iolog_timing FUZZ_SEED_CORPUS = ${FUZZ_PROGS:=_seed_corpus.zip} -FUZZ_LIBS = @LIBS@ $(LIB_FUZZING_ENGINE) +FUZZ_LIBS = $(LIB_FUZZING_ENGINE) @LIBS@ FUZZ_LDFLAGS = @LDFLAGS@ FUZZ_MAX_LEN = 4096 FUZZ_RUNS = 8192 @@ -176,13 +176,13 @@ host_port_test: $(HOST_PORT_TEST_OBJS) libsudo_iolog.la $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(HOST_PORT_TEST_OBJS) libsudo_iolog.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS) fuzz_iolog_json: $(FUZZ_IOLOG_JSON_OBJS) $(LIBFUZZSTUB) libsudo_iolog.la - $(LIBTOOL) $(LTFLAGS) --mode=link @FUZZ_LD@ -o $@ $(FUZZ_IOLOG_JSON_OBJS) libsudo_iolog.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(FUZZ_LDFLAGS) $(FUZZ_LIBS) + $(LIBTOOL) $(LTFLAGS) --mode=link @FUZZ_LD@ -o $@ $(FUZZ_IOLOG_JSON_OBJS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(FUZZ_LDFLAGS) $(FUZZ_LIBS) libsudo_iolog.la fuzz_iolog_legacy: $(FUZZ_IOLOG_LEGACY_OBJS) $(LIBFUZZSTUB) libsudo_iolog.la - $(LIBTOOL) $(LTFLAGS) --mode=link @FUZZ_LD@ -o $@ $(FUZZ_IOLOG_LEGACY_OBJS) libsudo_iolog.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(FUZZ_LDFLAGS) $(FUZZ_LIBS) + $(LIBTOOL) $(LTFLAGS) --mode=link @FUZZ_LD@ -o $@ $(FUZZ_IOLOG_LEGACY_OBJS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(FUZZ_LDFLAGS) $(FUZZ_LIBS) libsudo_iolog.la fuzz_iolog_timing: $(FUZZ_IOLOG_TIMING_OBJS) $(LIBFUZZSTUB) libsudo_iolog.la - $(LIBTOOL) $(LTFLAGS) --mode=link @FUZZ_LD@ -o $@ $(FUZZ_IOLOG_TIMING_OBJS) libsudo_iolog.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(FUZZ_LDFLAGS) $(FUZZ_LIBS) + $(LIBTOOL) $(LTFLAGS) --mode=link @FUZZ_LD@ -o $@ $(FUZZ_IOLOG_TIMING_OBJS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(FUZZ_LDFLAGS) $(FUZZ_LIBS) libsudo_iolog.la fuzz_iolog_json_seed_corpus.zip: tdir=fuzz_iolog_json.$$$$; \ diff --git a/lib/iolog/hostcheck.c b/lib/iolog/hostcheck.c index 0dee14b79..3eeabd262 100644 --- a/lib/iolog/hostcheck.c +++ b/lib/iolog/hostcheck.c @@ -24,6 +24,7 @@ #if defined(HAVE_OPENSSL) # include <sys/types.h> # include <sys/socket.h> +# include <netinet/in.h> # include <arpa/inet.h> # include <stdlib.h> # include <string.h> diff --git a/lib/util/Makefile.in b/lib/util/Makefile.in index 64a8aa4e7..e23dde9cd 100644 --- a/lib/util/Makefile.in +++ b/lib/util/Makefile.in @@ -105,7 +105,7 @@ PVS_LOG_OPTS = -a 'GA:1,2' -e -t errorfile -d $(PVS_IGNORE) # Regression tests TEST_PROGS = conf_test hltq_test parseln_test progname_test strsplit_test \ strtobool_test strtoid_test strtomode_test strtonum_test \ - parse_gids_test getgrouplist_test @COMPAT_TEST_PROGS@ + parse_gids_test getgids getgrouplist_test @COMPAT_TEST_PROGS@ TEST_LIBS = @LIBS@ TEST_LDFLAGS = @LDFLAGS@ @@ -114,7 +114,7 @@ LIBFUZZSTUB = $(top_builddir)/lib/fuzzstub/libsudo_fuzzstub.la LIB_FUZZING_ENGINE = @FUZZ_ENGINE@ FUZZ_PROGS = fuzz_sudo_conf FUZZ_SEED_CORPUS = ${FUZZ_PROGS:=_seed_corpus.zip} -FUZZ_LIBS = @LIBS@ $(LIB_FUZZING_ENGINE) +FUZZ_LIBS = $(LIB_FUZZING_ENGINE) @LIBS@ FUZZ_LDFLAGS = @LDFLAGS@ FUZZ_MAX_LEN = 4096 FUZZ_RUNS = 8192 @@ -170,6 +170,8 @@ STRSPLIT_TEST_OBJS = strsplit_test.lo strsplit.lo PARSE_GIDS_TEST_OBJS = parse_gids_test.lo gidlist.lo +GETGIDS_OBJS = getgids.lo getgrouplist.lo + GETGROUPLIST_TEST_OBJS = getgrouplist_test.lo getgrouplist.lo STRSIG_TEST_OBJS = strsig_test.lo sig2str.lo str2sig.lo @SIGNAME@ @@ -269,6 +271,9 @@ progname_test: $(PROGNAME_TEST_OBJS) parse_gids_test: $(PARSE_GIDS_TEST_OBJS) libsudo_util.la $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(PARSE_GIDS_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS) +getgids: $(GETGIDS_OBJS) libsudo_util.la + $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(GETGIDS_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS) + getgrouplist_test: $(GETGROUPLIST_TEST_OBJS) libsudo_util.la $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(GETGROUPLIST_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS) @@ -294,7 +299,7 @@ vsyslog_test: $(VSYSLOG_TEST_OBJS) libsudo_util.la $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(VSYSLOG_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS) fuzz_sudo_conf: $(FUZZ_SUDO_CONF_OBJS) $(LIBFUZZSTUB) libsudo_util.la - $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(FUZZ_SUDO_CONF_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(FUZZ_LDFLAGS) $(FUZZ_LIBS) + $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(FUZZ_SUDO_CONF_OBJS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(FUZZ_LDFLAGS) $(FUZZ_LIBS) libsudo_util.la fuzz_sudo_conf_seed_corpus.zip: tdir=fuzz_sudo_conf.$$$$; \ @@ -781,12 +786,26 @@ getentropy.i: $(srcdir)/getentropy.c $(incdir)/sudo_compat.h \ $(CC) -E -o $@ $(CPPFLAGS) $< getentropy.plog: getentropy.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getentropy.c --i-file $< --output-file $@ +getgids.lo: $(srcdir)/regress/getgrouplist/getgids.c \ + $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_fatal.h $(incdir)/sudo_plugin.h \ + $(incdir)/sudo_util.h $(top_builddir)/config.h + $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/getgrouplist/getgids.c +getgids.i: $(srcdir)/regress/getgrouplist/getgids.c \ + $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_fatal.h $(incdir)/sudo_plugin.h \ + $(incdir)/sudo_util.h $(top_builddir)/config.h + $(CC) -E -o $@ $(CPPFLAGS) $< +getgids.plog: getgids.i + rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/getgrouplist/getgids.c --i-file $< --output-file $@ getgrouplist.lo: $(srcdir)/getgrouplist.c $(incdir)/compat/nss_dbdefs.h \ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h \ $(incdir)/sudo_util.h $(top_builddir)/config.h $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getgrouplist.c getgrouplist.i: $(srcdir)/getgrouplist.c $(incdir)/compat/nss_dbdefs.h \ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ + $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h \ $(incdir)/sudo_util.h $(top_builddir)/config.h $(CC) -E -o $@ $(CPPFLAGS) $< getgrouplist.plog: getgrouplist.i @@ -1126,10 +1145,12 @@ pwrite.i: $(srcdir)/pwrite.c $(incdir)/sudo_compat.h $(top_builddir)/config.h pwrite.plog: pwrite.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/pwrite.c --i-file $< --output-file $@ rcstr.lo: $(srcdir)/rcstr.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ - $(incdir)/sudo_util.h $(top_builddir)/config.h + $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ + $(top_builddir)/config.h $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/rcstr.c rcstr.i: $(srcdir)/rcstr.c $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ - $(incdir)/sudo_util.h $(top_builddir)/config.h + $(incdir)/sudo_debug.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ + $(top_builddir)/config.h $(CC) -E -o $@ $(CPPFLAGS) $< rcstr.plog: rcstr.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/rcstr.c --i-file $< --output-file $@ diff --git a/lib/util/getgrouplist.c b/lib/util/getgrouplist.c index ae67bc025..96e91089e 100644 --- a/lib/util/getgrouplist.c +++ b/lib/util/getgrouplist.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: ISC * - * Copyright (c) 2010, 2011, 2013-2018 + * Copyright (c) 2010, 2011, 2013-2021 * Todd C. Miller <Todd.Miller@sudo.ws> * * Permission to use, copy, modify, and distribute this software for any @@ -41,6 +41,7 @@ #endif #include "sudo_compat.h" +#include "sudo_debug.h" #include "sudo_util.h" #ifndef HAVE_GETGROUPLIST @@ -70,16 +71,17 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, #ifndef HAVE_GETGROUPLIST_2 int grpsize, tries; #endif + debug_decl(sudo_getgrouplist2, SUDO_DEBUG_UTIL); /* For static group vector, just use getgrouplist(3). */ if (groups != NULL) - return getgrouplist(name, basegid, groups, ngroupsp); + debug_return_int(getgrouplist(name, basegid, groups, ngroupsp)); #ifdef HAVE_GETGROUPLIST_2 if ((ngroups = getgrouplist_2(name, basegid, groupsp)) == -1) - return -1; + debug_return_int(-1); *ngroupsp = ngroups; - return 0; + debug_return_int(0); #else grpsize = (int)sysconf(_SC_NGROUPS_MAX); if (grpsize < 0) @@ -93,12 +95,12 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, free(groups); groups = reallocarray(NULL, grpsize, sizeof(*groups)); if (groups == NULL) - return -1; + debug_return_int(-1); ngroups = grpsize; if (getgrouplist(name, basegid, groups, &ngroups) != -1) { *groupsp = groups; *ngroupsp = ngroups; - return 0; + debug_return_int(0); } if (ngroups == grpsize) { /* Failed for some reason other than ngroups too small. */ @@ -108,7 +110,7 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, grpsize = ngroups; } free(groups); - return -1; + debug_return_int(-1); #endif /* HAVE_GETGROUPLIST_2 */ } @@ -128,6 +130,7 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, int grpsize = *ngroupsp; int ret = -1; gid_t gid; + debug_decl(sudo_getgrouplist2, SUDO_DEBUG_UTIL); #ifdef HAVE_SETAUTHDB aix_setauthdb((char *) name, NULL); @@ -147,11 +150,11 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, } groups = reallocarray(NULL, grpsize, sizeof(*groups)); if (groups == NULL) - return -1; + debug_return_int(-1); } else { /* Static group vector. */ if (grpsize < 1) - return -1; + debug_return_int(-1); } /* We support BSD semantics where the first element is the base gid */ @@ -175,7 +178,7 @@ done: *groupsp = groups; *ngroupsp = ngroups; - return ret; + debug_return_int(ret); } #elif defined(HAVE_NSS_SEARCH) @@ -211,11 +214,12 @@ str2grp(const char *instr, int inlen, void *ent, char *buf, int buflen) const char *errstr; int yp = 0; id_t id; + debug_decl(str2grp, SUDO_DEBUG_UTIL); /* Must at least have space to copy instr -> buf. */ if (inlen >= buflen) - return NSS_STR_PARSE_ERANGE; - + debug_return_int(NSS_STR_PARSE_ERANGE); + /* Paranoia: buf and instr should be distinct. */ if (buf != instr) { memmove(buf, instr, inlen); @@ -223,7 +227,7 @@ str2grp(const char *instr, int inlen, void *ent, char *buf, int buflen) } if ((fieldsep = strchr(cp = fieldsep, ':')) == NULL) - return NSS_STR_PARSE_PARSE; + debug_return_int(NSS_STR_PARSE_PARSE); *fieldsep++ = '\0'; grp->gr_name = cp; @@ -237,12 +241,12 @@ str2grp(const char *instr, int inlen, void *ent, char *buf, int buflen) } if ((fieldsep = strchr(cp = fieldsep, ':')) == NULL) - return yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE; + debug_return_int(yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE); *fieldsep++ = '\0'; grp->gr_passwd = cp; if ((fieldsep = strchr(cp = fieldsep, ':')) == NULL) - return yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE; + debug_return_int(yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE); *fieldsep++ = '\0'; id = sudo_strtoid(cp, &errstr); if (errstr != NULL) { @@ -251,8 +255,8 @@ str2grp(const char *instr, int inlen, void *ent, char *buf, int buflen) * at the end of YP entries since it has no meaning. */ if (errno == ERANGE) - return NSS_STR_PARSE_ERANGE; - return yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE; + debug_return_int(NSS_STR_PARSE_ERANGE); + debug_return_int(yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE); } #ifdef GID_NOBODY /* Negative gids get mapped to nobody on Solaris. */ @@ -266,10 +270,10 @@ str2grp(const char *instr, int inlen, void *ent, char *buf, int buflen) grp->gr_mem = NULL; if (*fieldsep != '\0') { grp->gr_mem = gr_mem = (char **)ALIGN(buf + inlen + 1); - gr_end = (char **)((unsigned long)(buf + buflen) & ~ALIGNBYTES); + gr_end = (char **)((unsigned long)(buf + buflen) & ~ALIGNBYTES) - 1; for (;;) { - if (gr_mem == gr_end) - return NSS_STR_PARSE_ERANGE; /* out of space! */ + if (gr_mem >= gr_end) + debug_return_int(NSS_STR_PARSE_ERANGE); /* out of space! */ *gr_mem++ = cp; if (fieldsep == NULL) break; @@ -278,7 +282,7 @@ str2grp(const char *instr, int inlen, void *ent, char *buf, int buflen) } *gr_mem = NULL; } - return NSS_STR_PARSE_SUCCESS; + debug_return_int(NSS_STR_PARSE_SUCCESS); } static nss_status_t @@ -291,6 +295,10 @@ process_cstr(const char *instr, int inlen, struct nss_groupsbymem *gbm, struct group *grp; char **gr_mem; int error, i; + debug_decl(process_cstr, SUDO_DEBUG_UTIL); + + sudo_debug_printf(SUDO_DEBUG_INFO, "%s: parsing %.*s", __func__, + inlen, instr); /* Hack to let us check whether the query was handled by nscd or us. */ if (gbm->force_slow_way != 0) @@ -298,18 +306,20 @@ process_cstr(const char *instr, int inlen, struct nss_groupsbymem *gbm, buf = _nss_XbyY_buf_alloc(sizeof(struct group), NSS_BUFLEN_GROUP); if (buf == NULL) - return NSS_UNAVAIL; + debug_return_int(NSS_UNAVAIL); /* Parse groups file string -> struct group. */ grp = buf->result; error = (*gbm->str2ent)(instr, inlen, grp, buf->buffer, buf->buflen); - if (error || grp->gr_mem == NULL) + if (error != NSS_STR_PARSE_SUCCESS || grp->gr_mem == NULL) goto done; for (gr_mem = grp->gr_mem; *gr_mem != NULL; gr_mem++) { if (strcmp(*gr_mem, user) == 0) { + const int numgids = MIN(gbm->numgids, gbm->maxgids); + /* Append to gid_array unless gr_gid is a dupe. */ - for (i = 0; i < gbm->numgids; i++) { + for (i = 0; i < numgids; i++) { if (gbm->gid_array[i] == grp->gr_gid) goto done; /* already present */ } @@ -334,7 +344,7 @@ process_cstr(const char *instr, int inlen, struct nss_groupsbymem *gbm, } done: _nss_XbyY_buf_free(buf); - return ret; + debug_return_int(ret); } static nss_status_t @@ -358,6 +368,7 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, { struct nss_groupsbymem gbm; static DEFINE_NSS_DB_ROOT(db_root); + debug_decl(sudo_getgrouplist2, SUDO_DEBUG_UTIL); memset(&gbm, 0, sizeof(gbm)); gbm.username = name; @@ -374,13 +385,13 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, gbm.maxgids = NGROUPS_MAX; gbm.gid_array = reallocarray(NULL, gbm.maxgids, 4 * sizeof(GETGROUPS_T)); if (gbm.gid_array == NULL) - return -1; + debug_return_int(-1); gbm.maxgids <<= 2; gbm.process_cstr = process_cstr_dynamic; } else { /* Static group vector. */ if (gbm.maxgids <= 0) - return -1; + debug_return_int(-1); gbm.process_cstr = process_cstr_static; } @@ -414,7 +425,7 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, tmp = reallocarray(gbm.gid_array, gbm.maxgids, 2 * sizeof(GETGROUPS_T)); if (tmp == NULL) { free(gbm.gid_array); - return -1; + debug_return_int(-1); } gbm.gid_array = tmp; gbm.maxgids <<= 1; @@ -424,10 +435,10 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, *groupsp = gbm.gid_array; if (gbm.numgids <= gbm.maxgids) { *ngroupsp = gbm.numgids; - return 0; + debug_return_int(0); } *ngroupsp = gbm.maxgids; - return -1; + debug_return_int(-1); } #else /* !HAVE_GETGROUPLIST && !HAVE_GETGRSET && !HAVE__GETGROUPSBYMEMBER */ @@ -444,6 +455,7 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, int i, ngroups = 1; int ret = -1; struct group *grp; + debug_decl(sudo_getgrouplist2, SUDO_DEBUG_UTIL); if (groups == NULL) { /* Dynamically-sized group vector. */ @@ -452,12 +464,12 @@ sudo_getgrouplist2_v1(const char *name, GETGROUPS_T basegid, grpsize = NGROUPS_MAX; groups = reallocarray(NULL, grpsize, 4 * sizeof(*groups)); if (groups == NULL) - return -1; + debug_return_int(-1); grpsize <<= 2; } else { /* Static group vector. */ if (grpsize < 1) - return -1; + debug_return_int(-1); } /* We support BSD semantics where the first element is the base gid */ @@ -508,6 +520,6 @@ done: *groupsp = groups; *ngroupsp = ngroups; - return ret; + debug_return_int(ret); } #endif /* !HAVE_GETGROUPLIST && !HAVE_GETGRSET && !HAVE__GETGROUPSBYMEMBER */ diff --git a/lib/util/regress/getgrouplist/getgids.c b/lib/util/regress/getgrouplist/getgids.c new file mode 100644 index 000000000..6673c1731 --- /dev/null +++ b/lib/util/regress/getgrouplist/getgids.c @@ -0,0 +1,81 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2021 Todd C. Miller <Todd.Miller@sudo.ws> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#ifdef HAVE_STDBOOL_H +# include <stdbool.h> +#else +# include "compat/stdbool.h" +#endif +#include <unistd.h> +#include <pwd.h> +#include <grp.h> + +#define SUDO_ERROR_WRAP 0 + +#include "sudo_compat.h" +#include "sudo_fatal.h" +#include "sudo_util.h" + +sudo_dso_public int main(int argc, char *argv[]); + +/* + * Implement "id -G" using sudo_getgrouplist2(). + */ + +int +main(int argc, char *argv[]) +{ + char *username = NULL; + GETGROUPS_T *groups = NULL; + struct passwd *pw; + int i, ngroups; + gid_t basegid; + initprogname(argc > 0 ? argv[0] : "getgids"); + + if (getopt(argc, argv, "") != -1) { + fprintf(stderr, "usage: %s [user]\n", getprogname()); + return EXIT_FAILURE; + } + if (argc > 1) + username = argv[1]; + + if (username != NULL) { + if ((pw = getpwnam(username)) == NULL) + sudo_fatalx("unknown user name %s", username); + } else { + if ((pw = getpwuid(getuid())) == NULL) + sudo_fatalx("unknown user ID %u", (unsigned int)getuid()); + } + basegid = pw->pw_gid; + if ((username = strdup(pw->pw_name)) == NULL) + sudo_fatal(NULL); + + if (sudo_getgrouplist2(username, basegid, &groups, &ngroups) == -1) + sudo_fatal("sudo_getgroulist2"); + + for (i = 0; i < ngroups; i++) { + printf("%s%u", i ? " " : "", (unsigned int)groups[i]); + } + putchar('\n'); + return EXIT_SUCCESS; +} diff --git a/logsrvd/Makefile.in b/logsrvd/Makefile.in index 47d06a421..2e58ec976 100644 --- a/logsrvd/Makefile.in +++ b/logsrvd/Makefile.in @@ -104,7 +104,7 @@ LIBFUZZSTUB = $(top_builddir)/lib/fuzzstub/libsudo_fuzzstub.la LIB_FUZZING_ENGINE = @FUZZ_ENGINE@ FUZZ_PROGS = fuzz_logsrvd_conf FUZZ_SEED_CORPUS = ${FUZZ_PROGS:=_seed_corpus.zip} -FUZZ_LIBS = $(LIBS) $(LIB_FUZZING_ENGINE) +FUZZ_LIBS = $(LIB_FUZZING_ENGINE) $(LIBS) FUZZ_LDFLAGS = $(LDFLAGS) FUZZ_MAX_LEN = 4096 FUZZ_RUNS = 8192 diff --git a/logsrvd/logsrvd.c b/logsrvd/logsrvd.c index b06fe4a62..a5d16730a 100644 --- a/logsrvd/logsrvd.c +++ b/logsrvd/logsrvd.c @@ -244,7 +244,10 @@ connection_close(struct connection_closure *closure) /* Final state should be FINISHED except on error. */ sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, - "closure %p, final state %d", closure, closure->state); + "%s: closure %p, final state %d, relay_closure %p, " + "journal file %p, journal path %s", __func__, closure, + closure->state, closure->relay_closure, closure->journal, + closure->journal_path ? closure->journal_path : ""); /* * If we finished a client connection in store-and-forward mode, @@ -404,7 +407,7 @@ schedule_error_message(const char *errstr, struct connection_closure *closure) /* Prevent further reads from the client, just write the error. */ sudo_ev_del(closure->evbase, closure->read_ev); - if (errstr == NULL || closure->state == ERROR || closure->write_ev == NULL) + if (errstr == NULL || closure->error || closure->write_ev == NULL) goto done; /* Format error message and add to the write queue. */ @@ -419,7 +422,7 @@ schedule_error_message(const char *errstr, struct connection_closure *closure) ret = true; done: - closure->state = ERROR; + closure->error = true; debug_return_bool(ret); } @@ -963,8 +966,8 @@ server_msg_cb(int fd, int what, void *v) if (TAILQ_EMPTY(&closure->write_bufs)) { /* Write queue empty, check state. */ sudo_ev_del(closure->evbase, closure->write_ev); - if (closure->state == FINISHED || closure->state == SHUTDOWN || - closure->state == ERROR) + if (closure->error || closure->state == FINISHED || + closure->state == SHUTDOWN) goto finished; } } diff --git a/logsrvd/logsrvd.h b/logsrvd/logsrvd.h index f282b69ed..69bae730e 100644 --- a/logsrvd/logsrvd.h +++ b/logsrvd/logsrvd.h @@ -54,8 +54,7 @@ enum connection_status { RUNNING, EXITED, SHUTDOWN, - FINISHED, - ERROR + FINISHED }; /* @@ -106,6 +105,7 @@ struct connection_closure { int iolog_dir_fd; int sock; enum connection_status state; + bool error; bool tls; bool log_io; bool store_first; diff --git a/plugins/audit_json/audit_json.c b/plugins/audit_json/audit_json.c index acc4360c6..d792ff929 100644 --- a/plugins/audit_json/audit_json.c +++ b/plugins/audit_json/audit_json.c @@ -1,7 +1,7 @@ /* * SPDX-License-Identifier: ISC * - * Copyright (c) 2020 Todd C. Miller <Todd.Miller@sudo.ws> + * Copyright (c) 2020-2021 Todd C. Miller <Todd.Miller@sudo.ws> * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -553,10 +553,20 @@ audit_write_record(const char *audit_str, const char *plugin_name, goto oom; /* Write key=value objects. */ - if (!add_key_value_object(&json, "options", state.settings, settings_filter)) - goto oom; - if (!add_key_value_object(&json, "user_info", state.user_info, NULL)) - goto oom; + if (state.settings != NULL) { + if (!add_key_value_object(&json, "options", state.settings, settings_filter)) + goto oom; + } else { + sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, + "missing settings list"); + } + if (state.user_info != NULL) { + if (!add_key_value_object(&json, "user_info", state.user_info, NULL)) + goto oom; + } else { + sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, + "missing user_info list"); + } if (command_info != NULL) { if (!add_key_value_object(&json, "command_info", command_info, NULL)) goto oom; @@ -568,10 +578,20 @@ audit_write_record(const char *audit_str, const char *plugin_name, if (!sudo_json_add_value(&json, "submit_optind", &json_value)) goto oom; - if (!add_array(&json, "submit_argv", state.submit_argv)) - goto oom; - if (!add_array(&json, "submit_envp", state.submit_envp)) - goto oom; + if (state.submit_argv != NULL) { + if (!add_array(&json, "submit_argv", state.submit_argv)) + goto oom; + } else { + sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, + "missing submit_argv array"); + } + if (state.submit_envp != NULL) { + if (!add_array(&json, "submit_envp", state.submit_envp)) + goto oom; + } else { + sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO, + "missing submit_envp array"); + } if (run_argv != NULL) { if (!add_array(&json, "run_argv", run_argv)) goto oom; diff --git a/plugins/sudoers/defaults.h b/plugins/sudoers/defaults.h index cf83963ef..53a615170 100644 --- a/plugins/sudoers/defaults.h +++ b/plugins/sudoers/defaults.h @@ -104,7 +104,7 @@ struct early_default { #undef T_TIMESPEC #define T_TIMESPEC 0x010 #undef T_TIMEOUT -#define T_TIMEOUT 0x020 +#define T_TIMEOUT 0x011 #undef T_MASK #define T_MASK 0x0FF #undef T_BOOL diff --git a/plugins/sudoers/log_client.c b/plugins/sudoers/log_client.c index ddfa8a953..b79c7a610 100644 --- a/plugins/sudoers/log_client.c +++ b/plugins/sudoers/log_client.c @@ -1980,7 +1980,7 @@ log_server_open(struct log_details *details, struct timespec *now, /* Connect to log first available log server. */ if (!log_server_connect(closure)) { /* TODO: support offline logs if server unreachable */ - sudo_warn("%s", U_("unable to connect to log server")); + sudo_warnx("%s", U_("unable to connect to log server")); goto bad; } diff --git a/plugins/sudoers/policy.c b/plugins/sudoers/policy.c index 7c5938025..e42fb932d 100644 --- a/plugins/sudoers/policy.c +++ b/plugins/sudoers/policy.c @@ -588,7 +588,7 @@ bad: * Store the execution environment and other front-end settings. * Builds up the command_info list and sets argv and envp. * Consumes iolog_path if not NULL. - * Returns 1 on success and -1 on error. + * Returns true on success, else false. */ bool sudoers_policy_store_result(bool accepted, char *argv[], char *envp[], @@ -638,7 +638,7 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[], goto oom; } if (def_maxseq != NULL) { - if (asprintf(&command_info[info_len++], "maxseq=%s", def_maxseq) == -1) + if ((command_info[info_len++] = sudo_new_key_val("maxseq", def_maxseq)) == NULL) goto oom; } } @@ -715,8 +715,10 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[], glsize = sizeof("runas_groups=") - 1 + ((gidlist->ngids + 1) * (MAX_UID_T_LEN + 1)); gid_list = malloc(glsize); - if (gid_list == NULL) + if (gid_list == NULL) { + sudo_gidlist_delref(gidlist); goto oom; + } memcpy(gid_list, "runas_groups=", sizeof("runas_groups=") - 1); cp = gid_list + sizeof("runas_groups=") - 1; @@ -727,6 +729,7 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[], if (len < 0 || (size_t)len >= glsize - (cp - gid_list)) { sudo_warnx(U_("internal error, %s overflow"), __func__); free(gid_list); + sudo_gidlist_delref(gidlist); goto bad; } cp += len; @@ -737,6 +740,7 @@ sudoers_policy_store_result(bool accepted, char *argv[], char *envp[], if (len < 0 || (size_t)len >= glsize - (cp - gid_list)) { sudo_warnx(U_("internal error, %s overflow"), __func__); free(gid_list); + sudo_gidlist_delref(gidlist); goto bad; } cp += len; diff --git a/scripts/ltmain.sh b/scripts/ltmain.sh index 88bcf93af..960278152 100644 --- a/scripts/ltmain.sh +++ b/scripts/ltmain.sh @@ -8742,9 +8742,6 @@ func_mode_link () eval libname=\"$libname_spec\" ;; *) - test no = "$module" \ - && func_fatal_help "libtool library '$output' must begin with 'lib'" - if test no != "$need_lib_prefix"; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" diff --git a/scripts/mkpkg b/scripts/mkpkg index e40e367f3..86f48fcf5 100755 --- a/scripts/mkpkg +++ b/scripts/mkpkg @@ -132,10 +132,10 @@ fi # Choose compiler options by osversion if not cross-compiling. if [ "$crossbuild" = "false" ]; then case "$osversion" in - macos*) - # Use clang on macOS if present - if [ -z "$CC" -a -x /usr/bin/clang ]; then - CC=/usr/bin/clang; export CC + FreeBSD*|macos*) + # Use the system compiler on FreeBSD and macOS + if [ -z "$CC" -a -x /usr/bin/cc ]; then + CC=/usr/bin/cc; export CC fi ;; esac diff --git a/src/Makefile.in b/src/Makefile.in index ec2c2970a..108fa9c8f 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -64,6 +64,9 @@ LT_LDFLAGS = @LT_LDFLAGS@ # Flags to pass to libtool LTFLAGS = --tag=disable-static +# Build sudo_noexec as a module instead of a shared lib (except on macOS) +NOEXEC_MODULE = @NOEXEC_MODULE@ + # Address sanitizer flags ASAN_CFLAGS = @ASAN_CFLAGS@ ASAN_LDFLAGS = @ASAN_LDFLAGS@ @@ -175,15 +178,8 @@ Makefile: $(srcdir)/Makefile.in sudo: $(OBJS) $(LT_LIBS) @STATIC_SUDOERS@ $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(OBJS) $(SUDO_LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) @STATIC_SUDOERS@ -# We can't use -module here since you cannot preload a module on Darwin -libsudo_noexec.la: sudo_noexec.lo - $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) $(SSP_LDFLAGS) @LIBDL@ -o $@ sudo_noexec.lo -avoid-version -rpath $(noexecdir) -shrext .so - -# Some hackery is required to install this as sudo_noexec, not libsudo_noexec -sudo_noexec.la: libsudo_noexec.la - sed 's/libsudo_noexec/sudo_noexec/g' libsudo_noexec.la > sudo_noexec.la - if test -f .libs/libsudo_noexec.lai; then sed 's/libsudo_noexec/sudo_noexec/g' .libs/libsudo_noexec.lai > .libs/sudo_noexec.lai; fi - cp -p .libs/libsudo_noexec.so .libs/sudo_noexec.so +sudo_noexec.la: sudo_noexec.lo + $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) $(LDFLAGS) $(LT_LDFLAGS) $(SSP_LDFLAGS) @LIBDL@ -o $@ sudo_noexec.lo $(NOEXEC_MODULE) -avoid-version -rpath $(noexecdir) -shrext .so sesh: $(SESH_OBJS) $(LT_LIBS) $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(SESH_OBJS) $(LDFLAGS) $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(LIBS) diff --git a/src/load_plugins.c b/src/load_plugins.c index 3c2973e09..dd0ad3ef5 100644 --- a/src/load_plugins.c +++ b/src/load_plugins.c @@ -47,9 +47,7 @@ sudo_stat_plugin(struct plugin_info *info, char *fullpath, if (info->path[0] == '/') { if (strlcpy(fullpath, info->path, pathsize) >= pathsize) { - sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""), - _PATH_SUDO_CONF, info->lineno, info->symbol_name); - sudo_warnx(U_("%s: %s"), info->path, strerror(ENAMETOOLONG)); + errno = ENAMETOOLONG; goto done; } status = stat(fullpath, sb); @@ -60,9 +58,7 @@ sudo_stat_plugin(struct plugin_info *info, char *fullpath, /* Check static symbols. */ if (strcmp(info->path, SUDOERS_PLUGIN) == 0) { if (strlcpy(fullpath, info->path, pathsize) >= pathsize) { - sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""), - _PATH_SUDO_CONF, info->lineno, info->symbol_name); - sudo_warnx(U_("%s: %s"), info->path, strerror(ENAMETOOLONG)); + errno = ENAMETOOLONG; goto done; } /* Plugin is static, fake up struct stat. */ @@ -82,10 +78,7 @@ sudo_stat_plugin(struct plugin_info *info, char *fullpath, len = snprintf(fullpath, pathsize, "%s%s", sudo_conf_plugin_dir_path(), info->path); if (len < 0 || (size_t)len >= pathsize) { - sudo_warnx(U_("error in %s, line %d while loading plugin \"%s\""), - _PATH_SUDO_CONF, info->lineno, info->symbol_name); - sudo_warnx(U_("%s%s: %s"), sudo_conf_plugin_dir_path(), info->path, - strerror(ENAMETOOLONG)); + errno = ENAMETOOLONG; goto done; } /* Try parent dir for compatibility with old plugindir default. */ @@ -201,7 +194,7 @@ static bool plugin_exists(struct plugin_container_list *plugins, const char *symbol_name) { struct plugin_container *container; - debug_decl(find_plugin, SUDO_DEBUG_PLUGIN); + debug_decl(plugin_exists, SUDO_DEBUG_PLUGIN); TAILQ_FOREACH(container, plugins, entries) { if (strcmp(container->name, symbol_name) == 0) @@ -215,8 +208,9 @@ typedef struct generic_plugin * (plugin_clone_func)(void); struct generic_plugin * sudo_plugin_try_to_clone(void *so_handle, const char *symbol_name) { - debug_decl(sudo_plugin_clone, SUDO_DEBUG_PLUGIN); + debug_decl(sudo_plugin_try_to_clone, SUDO_DEBUG_PLUGIN); struct generic_plugin * plugin = NULL; + plugin_clone_func *clone_func; char *clone_func_name = NULL; if (asprintf(&clone_func_name, "%s_clone", symbol_name) < 0) { @@ -224,7 +218,7 @@ sudo_plugin_try_to_clone(void *so_handle, const char *symbol_name) goto cleanup; } - plugin_clone_func *clone_func = (plugin_clone_func *)sudo_dso_findsym(so_handle, clone_func_name); + clone_func = sudo_dso_findsym(so_handle, clone_func_name); if (clone_func) { plugin = (*clone_func)(); } diff --git a/src/sudo_edit.c b/src/sudo_edit.c index 41fc61c3a..15c75d8c4 100644 --- a/src/sudo_edit.c +++ b/src/sudo_edit.c @@ -529,6 +529,8 @@ selinux_edit_copy_tfiles(struct command_details *command_details, if (nfiles < 1) debug_return_int(0); + const int check_dir = ISSET(command_details->flags, CD_SUDOEDIT_CHECKDIR); + /* Construct common args for sesh */ sesh_nargs = 5 + (nfiles * 2) + 1; sesh_args = sesh_ap = reallocarray(NULL, sesh_nargs, sizeof(char *)); @@ -538,7 +540,7 @@ selinux_edit_copy_tfiles(struct command_details *command_details, } *sesh_ap++ = "sesh"; *sesh_ap++ = "-e"; - if (ISSET(command_details->flags, CD_SUDOEDIT_CHECKDIR)) { + if (check_dir) { if ((user_str = selinux_fmt_sudo_user()) == NULL) { sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); goto done; @@ -581,7 +583,11 @@ selinux_edit_copy_tfiles(struct command_details *command_details, if (tfd != -1) close(tfd); - if (sesh_ap - sesh_args > 3) { + /* + * check dir adds two more args to the array + */ + if ((!check_dir && sesh_ap - sesh_args > 3) + || (check_dir && sesh_ap - sesh_args > 5)) { /* Run sesh -e 1 <t1> <o1> ... <tn> <on> */ error = selinux_run_helper(command_details->cred.uid, command_details->cred.gid, command_details->cred.ngroups, command_details->cred.groups, sesh_args, diff --git a/src/ttyname.c b/src/ttyname.c index 47e4ab13f..631372e8d 100644 --- a/src/ttyname.c +++ b/src/ttyname.c @@ -131,8 +131,8 @@ get_process_ttyname(char *name, size_t namelen) ret = sudo_ttyname_dev(ki_proc->sudo_kp_tdev, name, namelen); if (ret == NULL) { sudo_debug_printf(SUDO_DEBUG_WARN|SUDO_DEBUG_LINENO|SUDO_DEBUG_ERRNO, - "unable to map device number %u to name", - ki_proc->sudo_kp_tdev); + "unable to map device number %lu to name", + (unsigned long)ki_proc->sudo_kp_tdev); } } } else { |