Check for LD_PRELOAD variants in configure instead of checkign cpp
symbols. In disable_execute(), compute the length of the new envp and allocate it once instead of reallocating on demand. Also append old value of LD_PRELOAD (if any) to the new value.
This commit is contained in:
13
config.h.in
13
config.h.in
@@ -745,6 +745,19 @@
|
||||
/* The syslog priority sudo will use for successful attempts. */
|
||||
#undef PRI_SUCCESS
|
||||
|
||||
/* The default value of preloaded objects (if any). */
|
||||
#undef RTLD_PRELOAD_DEFAULT
|
||||
|
||||
/* The delimiter to use when defining multiple preloaded objects. */
|
||||
#undef RTLD_PRELOAD_DELIM
|
||||
|
||||
/* An extra environment variable that is required to enable preloading (if
|
||||
any). */
|
||||
#undef RTLD_PRELOAD_ENABLE_VAR
|
||||
|
||||
/* The environment variable that controls preloading of dynamic objects. */
|
||||
#undef RTLD_PRELOAD_VAR
|
||||
|
||||
/* The user sudo should run commands as by default. */
|
||||
#undef RUNAS_DEFAULT
|
||||
|
||||
|
50
configure
vendored
50
configure
vendored
@@ -2946,6 +2946,11 @@ shadow_libs=
|
||||
shadow_libs_optional=
|
||||
CONFIGURE_ARGS="$@"
|
||||
|
||||
RTLD_PRELOAD_VAR="LD_PRELOAD"
|
||||
RTLD_PRELOAD_ENABLE_VAR=
|
||||
RTLD_PRELOAD_DELIM=":"
|
||||
RTLD_PRELOAD_DEFAULT=
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -13728,6 +13733,9 @@ fi
|
||||
|
||||
case "$host" in
|
||||
*-*-sunos4*)
|
||||
# LD_PRELOAD is space-delimited
|
||||
RTLD_PRELOAD_DELIM=" "
|
||||
|
||||
# getcwd(3) opens a pipe to getpwd(1)!?!
|
||||
BROKEN_GETCWD=1
|
||||
|
||||
@@ -13739,6 +13747,9 @@ case "$host" in
|
||||
shadow_funcs="getpwanam issecure"
|
||||
;;
|
||||
*-*-solaris2*)
|
||||
# LD_PRELOAD is space-delimited
|
||||
RTLD_PRELOAD_DELIM=" "
|
||||
|
||||
# To get the crypt(3) prototype (so we pass -Wall)
|
||||
OSDEFS="${OSDEFS} -D__EXTENSIONS__"
|
||||
# AFS support needs -lucb
|
||||
@@ -13855,6 +13866,8 @@ done
|
||||
# LDR_PRELOAD is only supported in AIX 5.3 and later
|
||||
if test $OSMAJOR -lt 5; then
|
||||
with_noexec=no
|
||||
else
|
||||
RTLD_PRELOAD_VAR="LDR_PRELOAD"
|
||||
fi
|
||||
|
||||
# AIX-specific functions
|
||||
@@ -14056,6 +14069,9 @@ $as_echo "yes, fixing locally" >&6; }
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
# ":DEFAULT" must be appended to _RLD_LIST
|
||||
RTLD_PRELOAD_VAR="_RLD_LIST"
|
||||
RTLD_PRELOAD_DEFAULT="DEFAULT"
|
||||
: ${mansectsu='8'}
|
||||
: ${mansectform='4'}
|
||||
;;
|
||||
@@ -14122,6 +14138,9 @@ if test "x$ac_cv_lib_sun_getpwnam" = xyes; then :
|
||||
fi
|
||||
|
||||
fi
|
||||
# ":DEFAULT" must be appended to _RLD_LIST
|
||||
RTLD_PRELOAD_VAR="_RLD_LIST"
|
||||
RTLD_PRELOAD_DEFAULT="DEFAULT"
|
||||
: ${mansectsu='1m'}
|
||||
: ${mansectform='4'}
|
||||
;;
|
||||
@@ -14313,11 +14332,15 @@ done
|
||||
CHECKSHADOW="false"
|
||||
test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
|
||||
: ${with_logincap='yes'}
|
||||
RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
|
||||
RTLD_PRELOAD_ENABLE_VAR="DYLD_FORCE_FLAT_NAMESPACE"
|
||||
;;
|
||||
*-*-nextstep*)
|
||||
# lockf() on is broken on the NeXT -- use flock instead
|
||||
ac_cv_func_lockf=no
|
||||
ac_cv_func_flock=yes
|
||||
RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
|
||||
RTLD_PRELOAD_ENABLE_VAR="DYLD_FORCE_FLAT_NAMESPACE"
|
||||
;;
|
||||
*-*-*sysv4*)
|
||||
: ${mansectsu='1m'}
|
||||
@@ -14333,6 +14356,29 @@ done
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -n "$with_noexec"; then
|
||||
cat >>confdefs.h <<EOF
|
||||
#define RTLD_PRELOAD_VAR "$RTLD_PRELOAD_VAR"
|
||||
EOF
|
||||
|
||||
cat >>confdefs.h <<EOF
|
||||
#define RTLD_PRELOAD_DELIM "$RTLD_PRELOAD_DELIM"
|
||||
EOF
|
||||
|
||||
if test -n "$RTLD_PRELOAD_DEFAULT"; then
|
||||
cat >>confdefs.h <<EOF
|
||||
#define RTLD_PRELOAD_DEFAULT "$RTLD_PRELOAD_DEFAULT"
|
||||
EOF
|
||||
|
||||
fi
|
||||
if test -n "$RTLD_PRELOAD_ENABLE_VAR"; then
|
||||
cat >>confdefs.h <<EOF
|
||||
#define RTLD_PRELOAD_ENABLE_VAR "$RTLD_PRELOAD_ENABLE_VAR"
|
||||
EOF
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
AUTH_REG=${AUTH_REG# }
|
||||
AUTH_EXCL=${AUTH_EXCL# }
|
||||
if test -n "$AUTH_EXCL"; then
|
||||
@@ -22313,6 +22359,10 @@ fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
44
configure.in
44
configure.in
@@ -184,6 +184,14 @@ shadow_libs=
|
||||
shadow_libs_optional=
|
||||
CONFIGURE_ARGS="$@"
|
||||
|
||||
dnl
|
||||
dnl LD_PRELOAD equivalents
|
||||
dnl
|
||||
RTLD_PRELOAD_VAR="LD_PRELOAD"
|
||||
RTLD_PRELOAD_ENABLE_VAR=
|
||||
RTLD_PRELOAD_DELIM=":"
|
||||
RTLD_PRELOAD_DEFAULT=
|
||||
|
||||
dnl
|
||||
dnl libc replacement functions live in compat
|
||||
dnl
|
||||
@@ -1465,6 +1473,9 @@ fi
|
||||
|
||||
case "$host" in
|
||||
*-*-sunos4*)
|
||||
# LD_PRELOAD is space-delimited
|
||||
RTLD_PRELOAD_DELIM=" "
|
||||
|
||||
# getcwd(3) opens a pipe to getpwd(1)!?!
|
||||
BROKEN_GETCWD=1
|
||||
|
||||
@@ -1476,6 +1487,9 @@ case "$host" in
|
||||
shadow_funcs="getpwanam issecure"
|
||||
;;
|
||||
*-*-solaris2*)
|
||||
# LD_PRELOAD is space-delimited
|
||||
RTLD_PRELOAD_DELIM=" "
|
||||
|
||||
# To get the crypt(3) prototype (so we pass -Wall)
|
||||
OSDEFS="${OSDEFS} -D__EXTENSIONS__"
|
||||
# AFS support needs -lucb
|
||||
@@ -1538,6 +1552,8 @@ case "$host" in
|
||||
# LDR_PRELOAD is only supported in AIX 5.3 and later
|
||||
if test $OSMAJOR -lt 5; then
|
||||
with_noexec=no
|
||||
else
|
||||
RTLD_PRELOAD_VAR="LDR_PRELOAD"
|
||||
fi
|
||||
|
||||
# AIX-specific functions
|
||||
@@ -1671,6 +1687,9 @@ case "$host" in
|
||||
]], [[exit(0);]])], [AC_MSG_RESULT(no)], [AC_MSG_RESULT([yes, fixing locally])
|
||||
sed 's:<acl.h>:<sys/acl.h>:g' < /usr/include/prot.h > prot.h
|
||||
])
|
||||
# ":DEFAULT" must be appended to _RLD_LIST
|
||||
RTLD_PRELOAD_VAR="_RLD_LIST"
|
||||
RTLD_PRELOAD_DEFAULT="DEFAULT"
|
||||
: ${mansectsu='8'}
|
||||
: ${mansectform='4'}
|
||||
;;
|
||||
@@ -1698,6 +1717,9 @@ case "$host" in
|
||||
if test "$OSMAJOR" -le 4; then
|
||||
AC_CHECK_LIB(sun, getpwnam, [LIBS="${LIBS} -lsun"])
|
||||
fi
|
||||
# ":DEFAULT" must be appended to _RLD_LIST
|
||||
RTLD_PRELOAD_VAR="_RLD_LIST"
|
||||
RTLD_PRELOAD_DEFAULT="DEFAULT"
|
||||
: ${mansectsu='1m'}
|
||||
: ${mansectform='4'}
|
||||
;;
|
||||
@@ -1840,11 +1862,15 @@ case "$host" in
|
||||
CHECKSHADOW="false"
|
||||
test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
|
||||
: ${with_logincap='yes'}
|
||||
RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
|
||||
RTLD_PRELOAD_ENABLE_VAR="DYLD_FORCE_FLAT_NAMESPACE"
|
||||
;;
|
||||
*-*-nextstep*)
|
||||
# lockf() on is broken on the NeXT -- use flock instead
|
||||
ac_cv_func_lockf=no
|
||||
ac_cv_func_flock=yes
|
||||
RTLD_PRELOAD_VAR="DYLD_INSERT_LIBRARIES"
|
||||
RTLD_PRELOAD_ENABLE_VAR="DYLD_FORCE_FLAT_NAMESPACE"
|
||||
;;
|
||||
*-*-*sysv4*)
|
||||
: ${mansectsu='1m'}
|
||||
@@ -1860,6 +1886,20 @@ case "$host" in
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl
|
||||
dnl Library preloading to support NOEXEC
|
||||
dnl
|
||||
if test -n "$with_noexec"; then
|
||||
SUDO_DEFINE_UNQUOTED(RTLD_PRELOAD_VAR, "$RTLD_PRELOAD_VAR")
|
||||
SUDO_DEFINE_UNQUOTED(RTLD_PRELOAD_DELIM, "$RTLD_PRELOAD_DELIM")
|
||||
if test -n "$RTLD_PRELOAD_DEFAULT"; then
|
||||
SUDO_DEFINE_UNQUOTED(RTLD_PRELOAD_DEFAULT, "$RTLD_PRELOAD_DEFAULT")
|
||||
fi
|
||||
if test -n "$RTLD_PRELOAD_ENABLE_VAR"; then
|
||||
SUDO_DEFINE_UNQUOTED(RTLD_PRELOAD_ENABLE_VAR, "$RTLD_PRELOAD_ENABLE_VAR")
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl Check for mixing mutually exclusive and regular auth methods
|
||||
dnl
|
||||
@@ -3308,6 +3348,10 @@ AH_TEMPLATE(HAVE_STRUCT_UTMP_UT_EXIT, [Define to 1 if `ut_exit' is a member of `
|
||||
AH_TEMPLATE(HAVE_STRUCT_UTMPX_UT_EXIT, [Define to 1 if `ut_exit' is a member of `struct utmpx'.])
|
||||
AH_TEMPLATE(HAVE___FUNC__, [Define to 1 if the compiler supports the C99 __func__ variable.])
|
||||
AH_TEMPLATE(SUDO_KRB5_INSTANCE, [An instance string to append to the username (separated by a slash) for Kerberos V authentication])
|
||||
AH_TEMPLATE(RTLD_PRELOAD_VAR, [The environment variable that controls preloading of dynamic objects.])
|
||||
AH_TEMPLATE(RTLD_PRELOAD_ENABLE_VAR, [An extra environment variable that is required to enable preloading (if any).])
|
||||
AH_TEMPLATE(RTLD_PRELOAD_DELIM, [The delimiter to use when defining multiple preloaded objects.])
|
||||
AH_TEMPLATE(RTLD_PRELOAD_DEFAULT, [The default value of preloaded objects (if any).])
|
||||
|
||||
dnl
|
||||
dnl Bits to copy verbatim into config.h.in
|
||||
|
@@ -53,9 +53,12 @@ static char * const *
|
||||
disable_execute(char *const envp[])
|
||||
{
|
||||
#ifdef _PATH_SUDO_NOEXEC
|
||||
char * const *ev;
|
||||
char *preload, **nenvp;
|
||||
int env_len = 0, env_size = 128;
|
||||
char *preload, **nenvp = NULL;
|
||||
int env_len, env_size;
|
||||
int preload_idx = -1;
|
||||
# ifdef RTLD_PRELOAD_ENABLE_VAR
|
||||
bool enabled = false;
|
||||
# endif
|
||||
#endif /* _PATH_SUDO_NOEXEC */
|
||||
debug_decl(disable_execute, SUDO_DEBUG_UTIL)
|
||||
|
||||
@@ -67,55 +70,59 @@ disable_execute(char *const envp[])
|
||||
#endif /* HAVE_PRIV_SET */
|
||||
|
||||
#ifdef _PATH_SUDO_NOEXEC
|
||||
nenvp = emalloc2(env_size, sizeof(char *));
|
||||
|
||||
/*
|
||||
* Preload a noexec file. For a list of LD_PRELOAD-alikes, see
|
||||
* http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html
|
||||
* XXX - need to support 32-bit and 64-bit variants
|
||||
*/
|
||||
# if defined(__darwin__) || defined(__APPLE__)
|
||||
nenvp[env_len++] = "DYLD_FORCE_FLAT_NAMESPACE=";
|
||||
preload = fmt_string("DYLD_INSERT_LIBRARIES", sudo_conf_noexec_path());
|
||||
# elif defined(__osf__) || defined(__sgi)
|
||||
easprintf(&preload, "_RLD_LIST=%s:DEFAULT", sudo_conf_noexec_path());
|
||||
# elif defined(_AIX)
|
||||
preload = fmt_string("LDR_PRELOAD", sudo_conf_noexec_path());
|
||||
|
||||
/* Count entries in envp, looking for LD_PRELOAD as we go. */
|
||||
for (env_len = 0; envp[env_len] != NULL; env_len++) {
|
||||
if (strncmp(envp[env_len], RTLD_PRELOAD_VAR "=", sizeof(RTLD_PRELOAD_VAR)) == 0) {
|
||||
preload_idx = env_len;
|
||||
continue;
|
||||
}
|
||||
#ifdef RTLD_PRELOAD_ENABLE_VAR
|
||||
if (strncmp(envp[env_len], RTLD_PRELOAD_ENABLE_VAR "=", sizeof(RTLD_PRELOAD_ENABLE_VAR)) == 0) {
|
||||
enabled = true;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Make a new copy of envp as needed. */
|
||||
env_size = env_len + 1 + (preload_idx == -1);
|
||||
#ifdef RTLD_PRELOAD_ENABLE_VAR
|
||||
if (!enabled)
|
||||
env_size++;
|
||||
#endif
|
||||
nenvp = emalloc2(env_size, sizeof(*envp));
|
||||
memcpy(nenvp, envp, env_len * sizeof(*envp));
|
||||
nenvp[env_len] = NULL;
|
||||
|
||||
/* Prepend our LD_PRELOAD to existing value or add new entry at the end. */
|
||||
if (preload_idx == -1) {
|
||||
# ifdef RTLD_PRELOAD_DEFAULT
|
||||
easprintf(&preload, "%s=%s%s%s", RTLD_PRELOAD_VAR, sudo_conf_noexec_path(), RTLD_PRELOAD_DELIM, RTLD_PRELOAD_DEFAULT);
|
||||
# else
|
||||
preload = fmt_string("LD_PRELOAD", sudo_conf_noexec_path());
|
||||
preload = fmt_string(RTLD_PRELOAD_VAR, sudo_conf_noexec_path());
|
||||
# endif
|
||||
if (preload == NULL)
|
||||
errorx(1, _("unable to allocate memory"));
|
||||
nenvp[env_len++] = preload;
|
||||
|
||||
for (ev = envp; *ev != NULL; ev++) {
|
||||
/*
|
||||
* Prune out existing preloaded libraries.
|
||||
* XXX - should append to new value instead.
|
||||
*/
|
||||
# if defined(__darwin__) || defined(__APPLE__)
|
||||
if (strncmp(*ev, "DYLD_INSERT_LIBRARIES=", sizeof("DYLD_INSERT_LIBRARIES=") - 1) == 0)
|
||||
continue;
|
||||
if (strncmp(*ev, "DYLD_FORCE_FLAT_NAMESPACE=", sizeof("DYLD_INSERT_LIBRARIES=") - 1) == 0)
|
||||
continue;
|
||||
# elif defined(__osf__) || defined(__sgi)
|
||||
if (strncmp(*ev, "_RLD_LIST=", sizeof("_RLD_LIST=") - 1) == 0)
|
||||
continue;
|
||||
# elif defined(_AIX)
|
||||
if (strncmp(*ev, "LDR_PRELOAD=", sizeof("LDR_PRELOAD=") - 1) == 0)
|
||||
continue;
|
||||
# else
|
||||
if (strncmp(*ev, "LD_PRELOAD=", sizeof("LD_PRELOAD=") - 1) == 0)
|
||||
continue;
|
||||
# endif
|
||||
/* Need at least 2 slots for current element and a NULL. */
|
||||
if (env_len + 2 > env_size) {
|
||||
env_size += 128;
|
||||
nenvp = erealloc3(nenvp, env_size, sizeof(char *));
|
||||
}
|
||||
nenvp[env_len++] = *ev;
|
||||
}
|
||||
nenvp[env_len] = NULL;
|
||||
} else {
|
||||
easprintf(&preload, "%s=%s%s%s", RTLD_PRELOAD_VAR, sudo_conf_noexec_path(), RTLD_PRELOAD_DELIM, nenvp[preload_idx]);
|
||||
nenvp[preload_idx] = preload;
|
||||
}
|
||||
# ifdef RTLD_PRELOAD_ENABLE_VAR
|
||||
if (!enabled) {
|
||||
nenvp[env_len++] = RTLD_PRELOAD_ENABLE_VAR "=";
|
||||
nenvp[env_len] = NULL;
|
||||
}
|
||||
# endif
|
||||
|
||||
/* Install new env pointer. */
|
||||
envp = nenvp;
|
||||
#endif /* _PATH_SUDO_NOEXEC */
|
||||
|
||||
|
Reference in New Issue
Block a user