]> granicus.if.org Git - sudo/commitdiff
Check for LD_PRELOAD variants in configure instead of checkign cpp
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 21 Feb 2012 18:26:02 +0000 (13:26 -0500)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 21 Feb 2012 18:26:02 +0000 (13:26 -0500)
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.

config.h.in
configure
configure.in
src/exec_common.c

index bab0510c1d12779b22294208f69548c019ab66bc..277b018f2c8af2f0e974bf830ff8a08adaf993fe 100644 (file)
 /* 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
 
index d6a578a491437e59365717ef68b5ac1fb50db438..513129acd0a8fe015a08700cb07bb0955dbcdd47 100755 (executable)
--- a/configure
+++ b/configure
@@ -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
 
 
 
+
+
+
+
 
 
 
index 5893b7da6e8bb8d605c9a40c483619d73a91f4c2..56e1b6042c87e59586959b178527a1b2a59dfab3 100644 (file)
@@ -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
index 389aa5c6424d153dc44c6afd35afa5b491cf3567..a4cd5400b067f7e1e8872655bcbe1044247ea86d 100644 (file)
@@ -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());
-# else
-    preload = fmt_string("LD_PRELOAD", 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)
+    /* 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;
-# 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)
+       }
+#ifdef RTLD_PRELOAD_ENABLE_VAR
+       if (strncmp(envp[env_len], RTLD_PRELOAD_ENABLE_VAR "=", sizeof(RTLD_PRELOAD_ENABLE_VAR)) == 0) {
+           enabled = true;
            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;
+#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(RTLD_PRELOAD_VAR, sudo_conf_noexec_path());
+# endif
+       if (preload == NULL)
+           errorx(1, _("unable to allocate memory"));
+       nenvp[env_len++] = preload;
+       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 */