summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <Todd.Miller@sudo.ws>2021-06-11 13:04:55 -0600
committerTodd C. Miller <Todd.Miller@sudo.ws>2021-06-11 13:04:55 -0600
commitd78aec38f166ce7c36e9d3f784591ee5b462b1b9 (patch)
tree6289978f781e1c96c258d6d8f2c6ea3e192f3f95
parent2f96f81ba88587b087bfd2e934824c2746a02590 (diff)
parent2f3f3774a5269644b90effe3a36ec13c2ae7c150 (diff)
downloadsudo-d78aec38f166ce7c36e9d3f784591ee5b462b1b9.tar.gz
Merge sudo 1.9.7p1 from tipSUDO_1_9_7p1
-rw-r--r--MANIFEST1
-rw-r--r--NEWS27
-rwxr-xr-xconfigure57
-rw-r--r--configure.ac31
-rw-r--r--doc/sudoreplay.man.in18
-rw-r--r--doc/sudoreplay.mdoc.in18
-rw-r--r--include/compat/nss_dbdefs.h18
-rw-r--r--lib/fuzzstub/fuzzstub.c2
-rw-r--r--lib/iolog/Makefile.in8
-rw-r--r--lib/iolog/hostcheck.c1
-rw-r--r--lib/util/Makefile.in31
-rw-r--r--lib/util/getgrouplist.c78
-rw-r--r--lib/util/regress/getgrouplist/getgids.c81
-rw-r--r--logsrvd/Makefile.in2
-rw-r--r--logsrvd/logsrvd.c13
-rw-r--r--logsrvd/logsrvd.h4
-rw-r--r--plugins/audit_json/audit_json.c38
-rw-r--r--plugins/sudoers/defaults.h2
-rw-r--r--plugins/sudoers/log_client.c2
-rw-r--r--plugins/sudoers/policy.c10
-rw-r--r--scripts/ltmain.sh3
-rwxr-xr-xscripts/mkpkg8
-rw-r--r--src/Makefile.in14
-rw-r--r--src/load_plugins.c20
-rw-r--r--src/sudo_edit.c10
-rw-r--r--src/ttyname.c4
26 files changed, 325 insertions, 176 deletions
diff --git a/MANIFEST b/MANIFEST
index 58de74183..dd910df38 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -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
diff --git a/NEWS b/NEWS
index 8f32e3a15..4a71b012a 100644
--- a/NEWS
+++ b/NEWS
@@ -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
diff --git a/configure b/configure
index f684810c8..d0f3491d1 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for sudo 1.9.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 {