mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-22 09:57:41 +00:00
If building with address sanitizer make sure its DSO is first.
Address sanitizer requires that it be preloaded before any other DSO in LD_PRELOAD. This should not be required for clang, which links in asan statically by default.
This commit is contained in:
parent
8f8a9c37b3
commit
dfe26f8c34
11
configure
vendored
11
configure
vendored
@ -28505,6 +28505,17 @@ fi
|
|||||||
|
|
||||||
printf "%s\n" "#define NO_LEAKS 1" >>confdefs.h
|
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 <<EOF
|
||||||
|
#define _PATH_ASAN_LIB "$libasan"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
else $as_nop
|
else $as_nop
|
||||||
|
|
||||||
|
19
configure.ac
19
configure.ac
@ -80,7 +80,6 @@ AC_SUBST([INSTALL_BACKUP])
|
|||||||
AC_SUBST([INSTALL_INTERCEPT])
|
AC_SUBST([INSTALL_INTERCEPT])
|
||||||
AC_SUBST([INSTALL_NOEXEC])
|
AC_SUBST([INSTALL_NOEXEC])
|
||||||
AC_SUBST([CHECK_INTERCEPT])
|
AC_SUBST([CHECK_INTERCEPT])
|
||||||
AC_SUBST([CHECK_NOEXEC])
|
|
||||||
AC_SUBST([PRELOAD_MODULE])
|
AC_SUBST([PRELOAD_MODULE])
|
||||||
AC_SUBST([DONT_LEAK_PATH_INFO])
|
AC_SUBST([DONT_LEAK_PATH_INFO])
|
||||||
AC_SUBST([BSDAUTH_USAGE])
|
AC_SUBST([BSDAUTH_USAGE])
|
||||||
@ -235,7 +234,6 @@ INSTALL_BACKUP=
|
|||||||
INSTALL_INTERCEPT=
|
INSTALL_INTERCEPT=
|
||||||
INSTALL_NOEXEC=
|
INSTALL_NOEXEC=
|
||||||
CHECK_INTERCEPT=
|
CHECK_INTERCEPT=
|
||||||
CHECK_NOEXEC=
|
|
||||||
PRELOAD_MODULE=-module
|
PRELOAD_MODULE=-module
|
||||||
exampledir='$(docdir)/examples'
|
exampledir='$(docdir)/examples'
|
||||||
devdir='$(srcdir)'
|
devdir='$(srcdir)'
|
||||||
@ -4511,6 +4509,18 @@ if test "$enable_sanitizer" != "no"; then
|
|||||||
AX_APPEND_FLAG([-fno-omit-frame-pointer], [CFLAGS])
|
AX_APPEND_FLAG([-fno-omit-frame-pointer], [CFLAGS])
|
||||||
])
|
])
|
||||||
AC_DEFINE(NO_LEAKS)
|
AC_DEFINE(NO_LEAKS)
|
||||||
|
dnl
|
||||||
|
dnl check for libasan.so so we can preload it before sudo_intercept.so
|
||||||
|
dnl gcc links asan dynamically, clang links it statically.
|
||||||
|
dnl
|
||||||
|
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
|
||||||
|
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])
|
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"
|
PROGS="${PROGS} sudo_noexec.la"
|
||||||
INSTALL_NOEXEC="install-noexec"
|
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])
|
SUDO_DEFINE_UNQUOTED(_PATH_SUDO_NOEXEC, "$noexec_file", [The fully qualified pathname of sudo_noexec.so])
|
||||||
else
|
else
|
||||||
SUDO_DEFINE_UNQUOTED(_PATH_SUDO_NOEXEC, NULL)
|
SUDO_DEFINE_UNQUOTED(_PATH_SUDO_NOEXEC, NULL)
|
||||||
|
@ -182,6 +182,10 @@
|
|||||||
# undef _PATH_SUDO_DEVSEARCH
|
# undef _PATH_SUDO_DEVSEARCH
|
||||||
#endif /* _PATH_SUDO_DEVSEARCH */
|
#endif /* _PATH_SUDO_DEVSEARCH */
|
||||||
|
|
||||||
|
#ifndef _PATH_ASAN_LIB
|
||||||
|
# undef _PATH_ASAN_LIB
|
||||||
|
#endif /* _PATH_ASAN_LIB */
|
||||||
|
|
||||||
#ifndef _PATH_VI
|
#ifndef _PATH_VI
|
||||||
# undef _PATH_VI
|
# undef _PATH_VI
|
||||||
#endif /* _PATH_VI */
|
#endif /* _PATH_VI */
|
||||||
|
@ -120,7 +120,7 @@ INIT_DIR=@INIT_DIR@
|
|||||||
INIT_SCRIPT=@INIT_SCRIPT@
|
INIT_SCRIPT=@INIT_SCRIPT@
|
||||||
RC_LINK=@RC_LINK@
|
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_LIBS = @LIBS@ $(LT_LIBS)
|
||||||
TEST_LDFLAGS = @LDFLAGS@
|
TEST_LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
@ -317,7 +317,7 @@ check: $(TEST_PROGS) check-fuzzer
|
|||||||
MALLOC_OPTIONS=S; export MALLOC_OPTIONS; \
|
MALLOC_OPTIONS=S; export MALLOC_OPTIONS; \
|
||||||
MALLOC_CONF="abort:true,junk:true"; export MALLOC_CONF; \
|
MALLOC_CONF="abort:true,junk:true"; export MALLOC_CONF; \
|
||||||
./check_net_ifs; \
|
./check_net_ifs; \
|
||||||
if test X"@CHECK_NOEXEC@" != X""; then \
|
if [ -f .libs/$(noexecfile) ]; then \
|
||||||
./check_noexec .libs/$(noexecfile); \
|
./check_noexec .libs/$(noexecfile); \
|
||||||
fi; \
|
fi; \
|
||||||
./check_ttyname; \
|
./check_ttyname; \
|
||||||
|
@ -41,7 +41,7 @@ sudo_preload_dso(char *envp[], const char *dso_file, int intercept_fd)
|
|||||||
{
|
{
|
||||||
char *preload = NULL;
|
char *preload = NULL;
|
||||||
char **nenvp = NULL;
|
char **nenvp = NULL;
|
||||||
int env_len;
|
int env_len, len;
|
||||||
int preload_idx = -1;
|
int preload_idx = -1;
|
||||||
int intercept_idx = -1;
|
int intercept_idx = -1;
|
||||||
bool fd_present = false;
|
bool fd_present = false;
|
||||||
@ -50,9 +50,23 @@ sudo_preload_dso(char *envp[], const char *dso_file, int intercept_fd)
|
|||||||
bool dso_enabled = false;
|
bool dso_enabled = false;
|
||||||
# else
|
# else
|
||||||
const bool dso_enabled = true;
|
const bool dso_enabled = true;
|
||||||
|
# endif
|
||||||
|
# ifdef _PATH_ASAN_LIB
|
||||||
|
char *dso_buf = NULL;
|
||||||
# endif
|
# endif
|
||||||
debug_decl(sudo_preload_dso, SUDO_DEBUG_UTIL);
|
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
|
* Preload a DSO file. For a list of LD_PRELOAD-alikes, see
|
||||||
* http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
|
* 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 (!dso_present) {
|
||||||
if (preload_idx == -1) {
|
if (preload_idx == -1) {
|
||||||
# ifdef RTLD_PRELOAD_DEFAULT
|
# 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);
|
RTLD_PRELOAD_DELIM, RTLD_PRELOAD_DEFAULT);
|
||||||
|
if (len == -1) {
|
||||||
|
goto oom;
|
||||||
|
}
|
||||||
# else
|
# else
|
||||||
preload = sudo_new_key_val(RTLD_PRELOAD_VAR, dso_file);
|
preload = sudo_new_key_val(RTLD_PRELOAD_VAR, dso_file);
|
||||||
# endif
|
|
||||||
if (preload == NULL) {
|
if (preload == NULL) {
|
||||||
goto oom;
|
goto oom;
|
||||||
}
|
}
|
||||||
|
# endif
|
||||||
envp[env_len++] = preload;
|
envp[env_len++] = preload;
|
||||||
envp[env_len] = NULL;
|
envp[env_len] = NULL;
|
||||||
} else {
|
} 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]);
|
dso_file, RTLD_PRELOAD_DELIM, envp[preload_idx]);
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
goto oom;
|
goto oom;
|
||||||
@ -165,7 +182,6 @@ sudo_preload_dso(char *envp[], const char *dso_file, int intercept_fd)
|
|||||||
# endif
|
# endif
|
||||||
if (!fd_present && intercept_fd != -1) {
|
if (!fd_present && intercept_fd != -1) {
|
||||||
char *fdstr;
|
char *fdstr;
|
||||||
int len;
|
|
||||||
|
|
||||||
len = asprintf(&fdstr, "SUDO_INTERCEPT_FD=%d", intercept_fd);
|
len = asprintf(&fdstr, "SUDO_INTERCEPT_FD=%d", intercept_fd);
|
||||||
if (len == -1) {
|
if (len == -1) {
|
||||||
@ -178,10 +194,16 @@ sudo_preload_dso(char *envp[], const char *dso_file, int intercept_fd)
|
|||||||
envp[env_len] = NULL;
|
envp[env_len] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
# ifdef _PATH_ASAN_LIB
|
||||||
|
free(dso_buf);
|
||||||
|
# endif
|
||||||
|
|
||||||
debug_return_ptr(envp);
|
debug_return_ptr(envp);
|
||||||
oom:
|
oom:
|
||||||
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
|
||||||
|
# ifdef _PATH_ASAN_LIB
|
||||||
|
free(dso_buf);
|
||||||
|
# endif
|
||||||
free(preload);
|
free(preload);
|
||||||
free(nenvp);
|
free(nenvp);
|
||||||
debug_return_ptr(NULL);
|
debug_return_ptr(NULL);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user