From 37abc1b7e40e51d0f0f128041e7f2bd9cc7032e9 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 28 Sep 2015 21:20:37 -0600 Subject: [PATCH] There's no point in trying to interpose protected versions of the exec family of functions. Many modern C libraries use hidden symbols for the functions and syscalls defined in libc such that they cannot be overridden inside libc itself. We have to just wrap all the exec variants plus system and popen. --- config.h.in | 66 -------------- configure | 216 +--------------------------------------------- configure.ac | 46 +--------- src/sudo_noexec.c | 107 ++++------------------- 4 files changed, 23 insertions(+), 412 deletions(-) diff --git a/config.h.in b/config.h.in index 2fcbaadd2..241479e61 100644 --- a/config.h.in +++ b/config.h.in @@ -829,33 +829,6 @@ /* Define to 1 if the system has the type `_Bool'. */ #undef HAVE__BOOL -/* Define to 1 if you have the `_execl' function. */ -#undef HAVE__EXECL - -/* Define to 1 if you have the `_execle' function. */ -#undef HAVE__EXECLE - -/* Define to 1 if you have the `_execlp' function. */ -#undef HAVE__EXECLP - -/* Define to 1 if you have the `_exect' function. */ -#undef HAVE__EXECT - -/* Define to 1 if you have the `_execv' function. */ -#undef HAVE__EXECV - -/* Define to 1 if you have the `_execve' function. */ -#undef HAVE__EXECVE - -/* Define to 1 if you have the `_execvP' function. */ -#undef HAVE__EXECVP - -/* Define to 1 if you have the `_execvpe' function. */ -#undef HAVE__EXECVPE - -/* Define to 1 if you have the `_fexecve' function. */ -#undef HAVE__FEXECVE - /* Define to 1 if you have the `_getpty' function. */ #undef HAVE__GETPTY @@ -868,42 +841,9 @@ /* Define to 1 if you have the `_nss_XbyY_buf_alloc' function. */ #undef HAVE__NSS_XBYY_BUF_ALLOC -/* Define to 1 if you have the `_posix_spawn' function. */ -#undef HAVE__POSIX_SPAWN - -/* Define to 1 if you have the `_posix_spawnp' function. */ -#undef HAVE__POSIX_SPAWNP - /* Define to 1 if you have the `_ttyname_dev' function. */ #undef HAVE__TTYNAME_DEV -/* Define to 1 if you have the `__execl' function. */ -#undef HAVE___EXECL - -/* Define to 1 if you have the `__execle' function. */ -#undef HAVE___EXECLE - -/* Define to 1 if you have the `__execlp' function. */ -#undef HAVE___EXECLP - -/* Define to 1 if you have the `__exect' function. */ -#undef HAVE___EXECT - -/* Define to 1 if you have the `__execv' function. */ -#undef HAVE___EXECV - -/* Define to 1 if you have the `__execve' function. */ -#undef HAVE___EXECVE - -/* Define to 1 if you have the `__execvP' function. */ -#undef HAVE___EXECVP - -/* Define to 1 if you have the `__execvpe' function. */ -#undef HAVE___EXECVPE - -/* Define to 1 if you have the `__fexecve' function. */ -#undef HAVE___FEXECVE - /* Define to 1 if the compiler supports the C99 __func__ variable. */ #undef HAVE___FUNC__ @@ -916,12 +856,6 @@ /* Define to 1 if you have the `__nss_XbyY_buf_alloc' function. */ #undef HAVE___NSS_XBYY_BUF_ALLOC -/* Define to 1 if you have the `__posix_spawn' function. */ -#undef HAVE___POSIX_SPAWN - -/* Define to 1 if you have the `__posix_spawnp' function. */ -#undef HAVE___POSIX_SPAWNP - /* Define to 1 if your crt0.o defines the __progname symbol for you. */ #undef HAVE___PROGNAME diff --git a/configure b/configure index 0a638a320..7ad1bf445 100755 --- a/configure +++ b/configure @@ -19887,10 +19887,8 @@ esac fi if test X"$with_noexec" != X"no"; then - # Check for underscore versions of standard exec functions - # unless we are using dyld symbole interposition - if test X"$dlyld_interpose" != X"yes"; then - for ac_func in _execl __execl + # Check for non-standard exec functions + for ac_func in exect execvP execvpe do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -19902,7 +19900,8 @@ _ACEOF fi done - for ac_func in _execle __execle + # Check for fexecve, posix_spawn, and posix_spawnp + for ac_func in fexecve posix_spawn posix_spawnp do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -19911,213 +19910,6 @@ if eval test \"x\$"$as_ac_var"\" = x"yes"; then : #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF -fi -done - - for ac_func in _execlp __execlp -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - for ac_func in _execv __execv -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - for ac_func in _execve __execve -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - for ac_func in _execvp __execvp -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - fi - # Check for non-standard exec functions including underscore versions - for ac_func in exect -do : - ac_fn_c_check_func "$LINENO" "exect" "ac_cv_func_exect" -if test "x$ac_cv_func_exect" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_EXECT 1 -_ACEOF - - if test X"$dlyld_interpose" != X"yes"; then - for ac_func in _exect __exect -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - fi - -fi -done - - for ac_func in execvP -do : - ac_fn_c_check_func "$LINENO" "execvP" "ac_cv_func_execvP" -if test "x$ac_cv_func_execvP" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_EXECVP 1 -_ACEOF - - if test X"$dlyld_interpose" != X"yes"; then - for ac_func in _execvP __execvP -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - fi - -fi -done - - for ac_func in execvpe -do : - ac_fn_c_check_func "$LINENO" "execvpe" "ac_cv_func_execvpe" -if test "x$ac_cv_func_execvpe" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_EXECVPE 1 -_ACEOF - - if test X"$dlyld_interpose" != X"yes"; then - for ac_func in _execvpe __execvpe -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - fi - -fi -done - - for ac_func in fexecve -do : - ac_fn_c_check_func "$LINENO" "fexecve" "ac_cv_func_fexecve" -if test "x$ac_cv_func_fexecve" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_FEXECVE 1 -_ACEOF - - if test X"$dlyld_interpose" != X"yes"; then - for ac_func in _fexecve __fexecve -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - fi - -fi -done - - # Check for posix_spawn, posix_spawnp and any underscore versions - for ac_func in posix_spawn -do : - ac_fn_c_check_func "$LINENO" "posix_spawn" "ac_cv_func_posix_spawn" -if test "x$ac_cv_func_posix_spawn" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_POSIX_SPAWN 1 -_ACEOF - - if test X"$dlyld_interpose" != X"yes"; then - for ac_func in _posix_spawn __posix_spawn -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - fi - -fi -done - - for ac_func in posix_spawnp -do : - ac_fn_c_check_func "$LINENO" "posix_spawnp" "ac_cv_func_posix_spawnp" -if test "x$ac_cv_func_posix_spawnp" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_POSIX_SPAWNP 1 -_ACEOF - - if test X"$dlyld_interpose" != X"yes"; then - for ac_func in _posix_spawnp __posix_spawnp -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - fi - fi done diff --git a/configure.ac b/configure.ac index 98a591ace..23c9158df 100644 --- a/configure.ac +++ b/configure.ac @@ -2674,48 +2674,10 @@ dnl dnl Function checks for sudo_noexec dnl if test X"$with_noexec" != X"no"; then - # Check for underscore versions of standard exec functions - # unless we are using dyld symbole interposition - if test X"$dlyld_interpose" != X"yes"; then - AC_CHECK_FUNCS([_execl __execl]) - AC_CHECK_FUNCS([_execle __execle]) - AC_CHECK_FUNCS([_execlp __execlp]) - AC_CHECK_FUNCS([_execv __execv]) - AC_CHECK_FUNCS([_execve __execve]) - AC_CHECK_FUNCS([_execvp __execvp]) - fi - # Check for non-standard exec functions including underscore versions - AC_CHECK_FUNCS([exect], [ - if test X"$dlyld_interpose" != X"yes"; then - AC_CHECK_FUNCS([_exect __exect]) - fi - ]) - AC_CHECK_FUNCS([execvP], [ - if test X"$dlyld_interpose" != X"yes"; then - AC_CHECK_FUNCS([_execvP __execvP]) - fi - ]) - AC_CHECK_FUNCS([execvpe], [ - if test X"$dlyld_interpose" != X"yes"; then - AC_CHECK_FUNCS([_execvpe __execvpe]) - fi - ]) - AC_CHECK_FUNCS([fexecve], [ - if test X"$dlyld_interpose" != X"yes"; then - AC_CHECK_FUNCS([_fexecve __fexecve]) - fi - ]) - # Check for posix_spawn, posix_spawnp and any underscore versions - AC_CHECK_FUNCS([posix_spawn], [ - if test X"$dlyld_interpose" != X"yes"; then - AC_CHECK_FUNCS([_posix_spawn __posix_spawn]) - fi - ]) - AC_CHECK_FUNCS([posix_spawnp], [ - if test X"$dlyld_interpose" != X"yes"; then - AC_CHECK_FUNCS([_posix_spawnp __posix_spawnp]) - fi - ]) + # Check for non-standard exec functions + AC_CHECK_FUNCS([exect execvP execvpe]) + # Check for fexecve, posix_spawn, and posix_spawnp + AC_CHECK_FUNCS([fexecve posix_spawn posix_spawnp]) fi dnl diff --git a/src/sudo_noexec.c b/src/sudo_noexec.c index ab002a82d..91bc994d3 100644 --- a/src/sudo_noexec.c +++ b/src/sudo_noexec.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004-2005, 2010-2013 Todd C. Miller + * Copyright (c) 2004-2005, 2010-2015 Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -50,11 +50,10 @@ typedef struct interpose_s { #endif /* - * Dummy versions of the exec(3) family of syscalls. It is not enough - * to just dummy out execve(2) since some C libraries use direct syscalls - * for the other functions instead of calling execve(2). Note that it is - * still possible to access the real syscalls via the syscall(2) interface - * but very few programs actually do that. + * Dummy versions of the exec(3) family of syscalls. It is not enough to + * just dummy out execve(2) since many C libraries do not call the public + * execve(2) interface. Note that it is still possible to access the real + * syscalls via the syscall(2) interface, but that is rarely done. */ #define DUMMY_BODY \ @@ -102,115 +101,39 @@ DUMMY_VA(execlp, const char *, const char *) DUMMY2(execv, const char *, char * const *) DUMMY2(execvp, const char *, char * const *) DUMMY3(execve, const char *, char * const *, char * const *) -DUMMY1(system, const char *) - -/* - * Private versions of the above. - */ -#ifdef HAVE__EXECL -DUMMY_VA(_execl, const char *, const char *) -#endif -#ifdef HAVE___EXECL -DUMMY_VA(__execl, const char *, const char *) -#endif -#ifdef HAVE__EXECLE -DUMMY_VA(_execle, const char *, const char *) -#endif -#ifdef HAVE___EXECLE -DUMMY_VA(__execle, const char *, const char *) -#endif -#ifdef HAVE__EXECLP -DUMMY_VA(_execlp, const char *, const char *) -#endif -#ifdef HAVE___EXECLP -DUMMY_VA(__execlp, const char *, const char *) -#endif -#ifdef HAVE__EXECV -DUMMY2(_execv, const char *, char * const *) -#endif -#ifdef HAVE___EXECV -DUMMY2(__execv, const char *, char * const *) -#endif -#ifdef HAVE__EXECVP -DUMMY2(_execvp, const char *, char * const *) -#endif -#ifdef HAVE___EXECVP -DUMMY2(__execvp, const char *, char * const *) -#endif -#ifdef HAVE__EXECVE -DUMMY3(_execve, const char *, char * const *, char * const *) -#endif -#ifdef HAVE___EXECVE -DUMMY3(__execve, const char *, char * const *, char * const *) -#endif /* - * Non-standard exec functions and corresponding private versions. + * Non-standard exec(3) functions and corresponding private versions. */ #ifdef HAVE_EXECVP DUMMY3(execvP, const char *, const char *, char * const *) #endif -#ifdef HAVE__EXECVP -DUMMY3(_execvP, const char *, const char *, char * const *) -#endif -#ifdef HAVE___EXECVP -DUMMY3(__execvP, const char *, const char *, char * const *) -#endif - #ifdef HAVE_EXECVPE DUMMY3(execvpe, const char *, char * const *, char * const *) #endif -#ifdef HAVE__EXECVPE -DUMMY3(_execvpe, const char *, char * const *, char * const *) -#endif -#ifdef HAVE___EXECVPE -DUMMY3(__execvpe, const char *, char * const *, char * const *) -#endif - #ifdef HAVE_EXECT DUMMY3(exect, const char *, char * const *, char * const *) #endif -#ifdef HAVE__EXECT -DUMMY3(_exect, const char *, char * const *, char * const *) -#endif -#ifdef HAVE___EXECT -DUMMY3(__exect, const char *, char * const *, char * const *) -#endif +/* + * Not all systems support fexecve(2), posix_spawn(2) and posix_spawnp(2). + */ #ifdef HAVE_FEXECVE DUMMY3(fexecve, int , char * const *, char * const *) #endif -#ifdef HAVE__FEXECVE -DUMMY3(_fexecve, int , char * const *, char * const *) -#endif -#ifdef HAVE___FEXECVE -DUMMY3(__fexecve, int , char * const *, char * const *) -#endif - -/* - * posix_spawn, posix_spawnp and any private versions. - */ #ifdef HAVE_POSIX_SPAWN DUMMY6(posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) #endif -#ifdef HAVE__POSIX_SPAWN -DUMMY6(_posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) -#endif -#ifdef HAVE___POSIX_SPAWN -DUMMY6(__posix_spawn, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) -#endif - #ifdef HAVE_POSIX_SPAWNP DUMMY6(posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) #endif -#ifdef HAVE_POSIX__SPAWNP -DUMMY6(_posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) -#endif -#ifdef HAVE_POSIX___SPAWNP -DUMMY6(__posix_spawnp, pid_t *, const char *, const posix_spawn_file_actions_t *, const posix_spawnattr_t *, char * const *, char * const *) -#endif -/* popen(3) returns FILE *, not int so we can't use a wrapper. */ +/* + * system(3) and popen(3). + * We can't use a wrapper for popen since it returns FILE *, not int. + */ +DUMMY1(system, const char *) + __dso_public FILE * FN_NAME(popen)(const char *c, const char *t) { -- 2.40.0