From 9a890467a7d7b697e161c2f8470cc8d0f6177325 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Mon, 7 Feb 2005 04:16:28 +0000 Subject: [PATCH] Use execve(2) and wrap the command in sh if we get ENOEXEC. --- INSTALL | 12 -------- config.h.in | 10 ------- configure | 81 ++++++++++++++++++---------------------------------- configure.in | 18 ------------ sudo.c | 14 +++++---- 5 files changed, 37 insertions(+), 98 deletions(-) diff --git a/INSTALL b/INSTALL index 72d3aeb79..c59e63615 100644 --- a/INSTALL +++ b/INSTALL @@ -292,14 +292,6 @@ Special features/options: the numeric id, *not* the symbolic name. Also note that this is actually set in the Makefile. The default is 0. - --with-execv - Use execv() to exec the command instead of execvp(). I can't think of - a reason to actually do this since execvp() is passed a fully qualified - pathname but someone might thoroughly distrust execvp(). Note that if - you define this you lose the ability to exec scripts that are missing - the '#!/bin/sh' cookie (like /bin/kill on SunOS and /etc/fastboot on - 4.3BSD). This is off by default. - --without-interfaces This option keeps sudo from trying to glean the ip address from each attached ethernet interface. It is only useful @@ -653,10 +645,6 @@ Digital UNIX: edit that. Linux: - NOTE: Reportedly, Linux's execvp(3) doesn't always execute - scripts that lack the "#!/some/shell" header correctly. - The workaround is to give all your scripts a proper - header. Versions of glibc 2.x previous to 2.0.7 have a broken lsearch(). You will need to either upgrade to glibc-2.0.7 or use sudo's version of lsearch(). To use sudo's lsearch(), comment out diff --git a/config.h.in b/config.h.in index cc36c79f8..05147ee43 100644 --- a/config.h.in +++ b/config.h.in @@ -519,10 +519,6 @@ /* The number of tries a user gets to enter their password. */ #undef TRIES_FOR_PASSWORD -/* Define to 1 if you wish to use execv() instead of execvp() when running - programs. */ -#undef USE_EXECV - /* Define to 1 if you want to insult the user for entering an incorrect password. */ #undef USE_INSULTS @@ -605,12 +601,6 @@ # define stat_sudoers lstat #endif -#ifdef USE_EXECV -# define EXECV execv -#else -# define EXECV execvp -#endif /* USE_EXECV */ - /* Macros to set/clear/test flags. */ #undef SET #define SET(t, f) ((t) |= (f)) diff --git a/configure b/configure index 9a9c091c6..88ac9075d 100755 --- a/configure +++ b/configure @@ -1097,7 +1097,6 @@ Optional Packages: --with-passwd-tries number of tries to enter password (default is 3) --with-timeout minutes before sudo asks for passwd again (def is 5 minutes) --with-password-timeout passwd prompt timeout in minutes (default is 5 minutes) - --with-execv use execv() instead of execvp() --with-tty-tickets use a different ticket file for each tty --with-insults insult the user for entering an incorrect password --with-all-insults include all the sudo insult sets @@ -2937,28 +2936,6 @@ _ACEOF echo "$as_me:$LINENO: result: $password_timeout" >&5 echo "${ECHO_T}$password_timeout" >&6 - -# Check whether --with-execv or --without-execv was given. -if test "${with_execv+set}" = set; then - withval="$with_execv" - case $with_execv in - yes) echo "$as_me:$LINENO: checking whether to use execvp or execv" >&5 -echo $ECHO_N "checking whether to use execvp or execv... $ECHO_C" >&6 - echo "$as_me:$LINENO: result: execv" >&5 -echo "${ECHO_T}execv" >&6 - cat >>confdefs.h <<\_ACEOF -#define USE_EXECV 1 -_ACEOF - - ;; - no) ;; - *) { { echo "$as_me:$LINENO: error: \"--with-execv does not take an argument.\"" >&5 -echo "$as_me: error: \"--with-execv does not take an argument.\"" >&2;} - { (exit 1); exit 1; }; } - ;; -esac -fi; - echo "$as_me:$LINENO: checking whether to use per-tty ticket files" >&5 echo $ECHO_N "checking whether to use per-tty ticket files... $ECHO_C" >&6 @@ -5511,7 +5488,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5514 "configure"' > conftest.$ac_ext + echo '#line 5491 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -6740,7 +6717,7 @@ fi # Provide some information about the compiler. -echo "$as_me:6743:" \ +echo "$as_me:6720:" \ "checking for Fortran 77 compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 @@ -7771,11 +7748,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7774: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7751: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7778: \$? = $ac_status" >&5 + echo "$as_me:7755: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -8003,11 +7980,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8006: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7983: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:8010: \$? = $ac_status" >&5 + echo "$as_me:7987: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -8070,11 +8047,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:8073: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8050: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:8077: \$? = $ac_status" >&5 + echo "$as_me:8054: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10156,7 +10133,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:12390: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12417: \$? = $ac_status" >&5 + echo "$as_me:12394: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -12477,11 +12454,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12480: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12457: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12484: \$? = $ac_status" >&5 + echo "$as_me:12461: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -13767,7 +13744,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5) + (eval echo "\"\$as_me:14667: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14694: \$? = $ac_status" >&5 + echo "$as_me:14671: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -14754,11 +14731,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14757: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14734: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14761: \$? = $ac_status" >&5 + echo "$as_me:14738: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -16688,11 +16665,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16691: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16668: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16695: \$? = $ac_status" >&5 + echo "$as_me:16672: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -16920,11 +16897,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16923: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16900: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16927: \$? = $ac_status" >&5 + echo "$as_me:16904: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings @@ -16987,11 +16964,11 @@ else -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16990: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16967: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:16994: \$? = $ac_status" >&5 + echo "$as_me:16971: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -19073,7 +19050,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext < 0) exit(0); else - EXECV(safe_cmnd, NewArgv); /* run the command */ + execve(safe_cmnd, NewArgv, new_environ); #else exit(0); #endif /* PROFILING */ /* - * If we got here then the exec() failed... + * If we got here then execve() failed... */ + if (errno == ENOEXEC) { + char **av = emalloc2(NewArgc + 2, sizeof(char *)); + av[0] = "sh"; + av[1] = safe_cmnd; + memcpy(av + 2, NewArgv + 1, NewArgc * sizeof(char *)); + execve(_PATH_BSHELL, av, new_environ); + } warning("unable to execute %s", safe_cmnd); exit(127); } else if (ISSET(validated, FLAG_NO_USER) || (validated & FLAG_NO_HOST)) { -- 2.40.0