diff --git a/configure b/configure index 0fc4fe2cf..c056837bb 100755 --- a/configure +++ b/configure @@ -28505,6 +28505,17 @@ fi printf "%s\n" "#define NO_LEAKS 1" >>confdefs.h + case `$CC --version 2>&1` in + *gcc*) + libasan=`$CC -print-file-name=libasan.so 2>/dev/null` + if test -n "$libasan" -a X"$libasan" != X"libasan.so"; then + cat >>confdefs.h <&1` in + *gcc*) + libasan=`$CC -print-file-name=libasan.so 2>/dev/null` + if test -n "$libasan" -a X"$libasan" != X"libasan.so"; then + SUDO_DEFINE_UNQUOTED(_PATH_ASAN_LIB, "$libasan", [Path to the libasan.so shared library]) + fi + ;; + esac ], [ AC_MSG_ERROR([$CC does not support the $enable_sanitizer flag]) ]) @@ -4807,11 +4817,6 @@ if test X"$with_noexec" != X"no"; then PROGS="${PROGS} sudo_noexec.la" INSTALL_NOEXEC="install-noexec" - # Can't use sanitizers with LD_PRELOAD - if test "$enable_sanitizer" != "yes"; then - CHECK_NOEXEC=check_noexec - fi - SUDO_DEFINE_UNQUOTED(_PATH_SUDO_NOEXEC, "$noexec_file", [The fully qualified pathname of sudo_noexec.so]) else SUDO_DEFINE_UNQUOTED(_PATH_SUDO_NOEXEC, NULL) diff --git a/pathnames.h.in b/pathnames.h.in index 5d86a73c4..76d7bb231 100644 --- a/pathnames.h.in +++ b/pathnames.h.in @@ -182,6 +182,10 @@ # undef _PATH_SUDO_DEVSEARCH #endif /* _PATH_SUDO_DEVSEARCH */ +#ifndef _PATH_ASAN_LIB +# undef _PATH_ASAN_LIB +#endif /* _PATH_ASAN_LIB */ + #ifndef _PATH_VI # undef _PATH_VI #endif /* _PATH_VI */ diff --git a/src/Makefile.in b/src/Makefile.in index 60402a814..e84e40b28 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -120,7 +120,7 @@ INIT_DIR=@INIT_DIR@ INIT_SCRIPT=@INIT_SCRIPT@ RC_LINK=@RC_LINK@ -TEST_PROGS = check_net_ifs @CHECK_NOEXEC@ check_ttyname +TEST_PROGS = check_net_ifs check_noexec check_ttyname TEST_LIBS = @LIBS@ $(LT_LIBS) TEST_LDFLAGS = @LDFLAGS@ @@ -317,7 +317,7 @@ check: $(TEST_PROGS) check-fuzzer MALLOC_OPTIONS=S; export MALLOC_OPTIONS; \ MALLOC_CONF="abort:true,junk:true"; export MALLOC_CONF; \ ./check_net_ifs; \ - if test X"@CHECK_NOEXEC@" != X""; then \ + if [ -f .libs/$(noexecfile) ]; then \ ./check_noexec .libs/$(noexecfile); \ fi; \ ./check_ttyname; \ diff --git a/src/exec_preload.c b/src/exec_preload.c index af3f899a6..0288a27c6 100644 --- a/src/exec_preload.c +++ b/src/exec_preload.c @@ -41,7 +41,7 @@ sudo_preload_dso(char *envp[], const char *dso_file, int intercept_fd) { char *preload = NULL; char **nenvp = NULL; - int env_len; + int env_len, len; int preload_idx = -1; int intercept_idx = -1; bool fd_present = false; @@ -50,9 +50,23 @@ sudo_preload_dso(char *envp[], const char *dso_file, int intercept_fd) bool dso_enabled = false; # else const bool dso_enabled = true; +# endif +# ifdef _PATH_ASAN_LIB + char *dso_buf = NULL; # endif debug_decl(sudo_preload_dso, SUDO_DEBUG_UTIL); +# ifdef _PATH_ASAN_LIB + /* + * The address sanitizer DSO needs to be first in the list. + */ + len = asprintf(&dso_buf, "%s%c%s", _PATH_ASAN_LIB, RTLD_PRELOAD_DELIM, + dso_file); + if (len == -1) + goto oom; + dso_file = dso_buf; +# endif + /* * Preload a DSO file. For a list of LD_PRELOAD-alikes, see * http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html @@ -138,18 +152,21 @@ sudo_preload_dso(char *envp[], const char *dso_file, int intercept_fd) if (!dso_present) { if (preload_idx == -1) { # ifdef RTLD_PRELOAD_DEFAULT - asprintf(&preload, "%s=%s%c%s", RTLD_PRELOAD_VAR, dso_file, + len = asprintf(&preload, "%s=%s%c%s", RTLD_PRELOAD_VAR, dso_file, RTLD_PRELOAD_DELIM, RTLD_PRELOAD_DEFAULT); + if (len == -1) { + goto oom; + } # else preload = sudo_new_key_val(RTLD_PRELOAD_VAR, dso_file); -# endif if (preload == NULL) { goto oom; } +# endif envp[env_len++] = preload; envp[env_len] = NULL; } else { - int len = asprintf(&preload, "%s=%s%c%s", RTLD_PRELOAD_VAR, + len = asprintf(&preload, "%s=%s%c%s", RTLD_PRELOAD_VAR, dso_file, RTLD_PRELOAD_DELIM, envp[preload_idx]); if (len == -1) { goto oom; @@ -165,7 +182,6 @@ sudo_preload_dso(char *envp[], const char *dso_file, int intercept_fd) # endif if (!fd_present && intercept_fd != -1) { char *fdstr; - int len; len = asprintf(&fdstr, "SUDO_INTERCEPT_FD=%d", intercept_fd); if (len == -1) { @@ -178,10 +194,16 @@ sudo_preload_dso(char *envp[], const char *dso_file, int intercept_fd) envp[env_len] = NULL; } } +# ifdef _PATH_ASAN_LIB + free(dso_buf); +# endif debug_return_ptr(envp); oom: sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); +# ifdef _PATH_ASAN_LIB + free(dso_buf); +# endif free(preload); free(nenvp); debug_return_ptr(NULL);