diff --git a/src/Makefile.in b/src/Makefile.in index d191dd4e3..a2b6edd4a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -863,12 +863,14 @@ sudo_edit.i: $(srcdir)/sudo_edit.c $(incdir)/compat/stdbool.h \ sudo_edit.plog: sudo_edit.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_edit.c --i-file $< --output-file $@ sudo_intercept.lo: $(srcdir)/sudo_intercept.c $(incdir)/compat/stdbool.h \ - $(incdir)/sudo_compat.h $(top_builddir)/config.h \ - $(top_builddir)/pathnames.h + $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \ + $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ + $(top_builddir)/config.h $(top_builddir)/pathnames.h $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/sudo_intercept.c sudo_intercept.i: $(srcdir)/sudo_intercept.c $(incdir)/compat/stdbool.h \ - $(incdir)/sudo_compat.h $(top_builddir)/config.h \ - $(top_builddir)/pathnames.h + $(incdir)/sudo_compat.h $(incdir)/sudo_debug.h \ + $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \ + $(top_builddir)/config.h $(top_builddir)/pathnames.h $(CC) -E -o $@ $(CPPFLAGS) $< sudo_intercept.plog: sudo_intercept.i rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/sudo_intercept.c --i-file $< --output-file $@ diff --git a/src/sudo_intercept.c b/src/sudo_intercept.c index dcecd2514..a620c5ebf 100644 --- a/src/sudo_intercept.c +++ b/src/sudo_intercept.c @@ -44,6 +44,8 @@ #endif #include "sudo_compat.h" +#include "sudo_debug.h" +#include "sudo_util.h" #include "pathnames.h" extern bool command_allowed(const char *cmnd, char * const argv[], char * const envp[], char **ncmnd, char ***nargv, char ***nenvp); @@ -89,29 +91,42 @@ __attribute__((__section__("__DATA,__interpose"))) = { typedef int (*sudo_fn_execve_t)(const char *, char *const *, char *const *); -sudo_dso_public int -execve(const char *cmnd, char * const argv[], char * const envp[]) +# if defined(HAVE_SHL_LOAD) +static void * +sudo_shl_get_next(const char *symbol, short type) { - char *ncmnd = NULL, **nargv = NULL, **nenvp = NULL; -# if defined(HAVE_DLOPEN) - void *fn = dlsym(RTLD_NEXT, "execve"); -# elif defined(HAVE_SHL_LOAD) - const char *name, *myname = _PATH_SUDO_INTERCEPT; + const char *name, *myname; struct shl_descriptor *desc; void *fn = NULL; int idx = 0; + debug_decl(sudo_shl_get_next, SUDO_DEBUG_EXEC); - /* Search for execve() but skip this shared object. */ - myname = sudo_basename(myname); + /* Search for symbol but skip this shared object. */ + /* XXX - could be set to a different path in sudo.conf */ + myname = sudo_basename(_PATH_SUDO_INTERCEPT); while (shl_get(idx++, &desc) == 0) { name = sudo_basename(desc->filename); if (strcmp(name, myname) == 0) continue; - if (shl_findsym(&desc->handle, "execve", TYPE_PROCEDURE, &fn) == 0) + if (shl_findsym(&desc->handle, symbol, type, &fn) == 0) break; } -# else + + debug_return_ptr(fn); +} +# endif /* HAVE_SHL_LOAD */ + +sudo_dso_public int +execve(const char *cmnd, char * const argv[], char * const envp[]) +{ + char *ncmnd = NULL, **nargv = NULL, **nenvp = NULL; void *fn = NULL; + debug_decl(execve, SUDO_DEBUG_EXEC); + +# if defined(HAVE_DLOPEN) + fn = dlsym(RTLD_NEXT, "execve"); +# elif defined(HAVE_SHL_LOAD) + fn = sudo_shl_get_next("execve", TYPE_PROCEDURE); # endif if (fn == NULL) { errno = EACCES; diff --git a/src/sudo_intercept_common.c b/src/sudo_intercept_common.c index 6b46d4d72..85d3db27a 100644 --- a/src/sudo_intercept_common.c +++ b/src/sudo_intercept_common.c @@ -79,6 +79,7 @@ sudo_interposer_init(void) sudo_debug_register("sudo_intercept.so", NULL, NULL, sudo_conf_debug_files("sudo_intercept.so")); } + sudo_debug_enter(__func__, __FILE__, __LINE__, sudo_debug_subsys); /* * Missing SUDO_INTERCEPT_FD will result in execve() failure. @@ -91,33 +92,35 @@ sudo_interposer_init(void) char ch = INTERCEPT_REQ_SEC; int fd; + sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO, "%s", *p); + fd = sudo_strtonum(fdstr, 0, INT_MAX, &errstr); if (errstr != NULL) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, "invalid SUDO_INTERCEPT_FD: %s: %s", fdstr, errstr); - break; + debug_return; } /* Request secret from parent. */ if (send(fd, &ch, sizeof(ch), 0) != sizeof(ch)) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, - "unable to request secret: %s", strerror(errno)); - break; + "unable to request secret on fd %d: %s", fd, + strerror(errno)); + debug_return; } if (recv(fd, &secret, sizeof(secret), 0) != sizeof(secret)) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, - "unable to read secret: %s", strerror(errno)); - break; + "unable to read secret on fd %d: %s", fd, + strerror(errno)); + debug_return; } intercept_sock = fd; - break; + debug_return; } } - if (intercept_sock == -1) { - sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, - "SUDO_INTERCEPT_FD not found in environment"); - } + sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO, + "SUDO_INTERCEPT_FD not found in environment"); } debug_return; } @@ -216,7 +219,7 @@ intercept_send_fd(int sock, int fd) if (errno != EAGAIN && errno != EINTR) break; } - sudo_warn("sendmsg"); + sudo_warn("sendmsg(%d)", sock); debug_return_bool(false); }