]> granicus.if.org Git - sudo/commitdiff
Restrict default creation of PIE binaries (-fPIE and -pie) to Linux.
authorTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 10 Feb 2015 03:52:50 +0000 (20:52 -0700)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Tue, 10 Feb 2015 03:52:50 +0000 (20:52 -0700)
OpenBSD also supports PIE but enables it by default so we don't
need to do anything.  This fixes problems on systems with a version
of GNU ld that accepts -pie but where the run-time linker doesn't
actually support PIE.  Also verify that a trivial PIE binary works
unless PIE is explicitly enabled.

--HG--
branch : 1.7

INSTALL
NEWS
TROUBLESHOOTING
aclocal.m4
configure
configure.in

diff --git a/INSTALL b/INSTALL
index 91b79751ff4ee5f73242b240edc902c0b8d8e237..1c2e4e6766fea034b471634defe7e06d8c2069ec 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -121,6 +121,18 @@ Special features/options:
        so configure and the compiler will look there for libraries.
        Multiple directories may be specified as with --with-incpath.
 
+  --enable-pie
+       Build sudo and related programs as as a position independent
+       executables (PIE).  This improves the effectiveness of address
+       space layout randomization (ASLR) on systems that support it.
+       Sudo will create PIE binaries by default on Linux systems.
+
+  --disable-pie
+       Disable the creation of position independent executables (PIE),
+       even if the compiler creates PIE binaries by default.  This
+       option may be needed on some Linux systems where PIE binaries
+       are not fully supported.
+
   --with-rpath
        Tells configure to use -Rpath in addition to -Lpath when
        passing library paths to the loader.  This option is on
@@ -657,11 +669,6 @@ The following options are also configurable at runtime:
        _FORTIFY_SOURCE defined to 2, building with -fstack-protector
        and linking with -zrelro, where supported.
 
-  --disable-pie
-       Disable the creation of position independent executables (PIE)
-        even when the compiler and linker support them.
-       By default, sudo will be built as a PIE where possible.
-
   --enable-admin-flag
        Enable the creation of an Ubuntu-style admin flag file
        the first time sudo is run.
diff --git a/NEWS b/NEWS
index 4e1b932b8bbdea7e0970e0469dd1cb58a6605aae..e22a321992ca4ea67ce15884f9232134d75d1148 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,10 @@ What's new in Sudo 1.7.10p9?
  * The TZ environment variable is now checked for safety instead
    of simply being copied to the environment of the command.
 
+ * Sudo now only builds Position Independent Executables (PIE)
+   by default on Linux systems and verifies that a trivial test
+   program builds and runs.
+
 What's new in Sudo 1.7.10p8?
 
  * Sudo's exit code now indicates a failure if the user does not
index e5e1bdebd3112aa52f1ffdb4fe1d023dadb0b484..9ce9ef4b0150c2db38e6851254704dfa5a8c794d 100644 (file)
@@ -266,6 +266,15 @@ A) AIX's Enhanced RBAC is preventing sudo from running.  To fix
            innateprivs = PV_DAC_GID,PV_DAC_O,PV_DAC_R,PV_DAC_UID,PV_DAC_W,PV_DAC_X,PV_FS_CHOWN,PV_PROC_ENV,PV_PROC_PRIO,PV_PROC_RAC
            secflags = FSF_EPS
 
+Q) Sudo configures and builds without error but when I run it I get
+   a Segmentation fault.
+A) If you are on a Linux system, the first thing to try is to run
+   configure with the --disable-pie option, then "make clean" and
+   "make".  If that fixes the problem then your operating system
+   does not properly support position independent executables.
+   Please send a message to sudo@sudo.ws with system details such
+   as the Linux distro, kernel version and CPU architecture.
+
 Q) How do you pronounce `sudo'?
 A) The official pronunciation is soo-doo (for su "do").  However, an
    alternate pronunciation, a homophone of "pseudo", is also common.
index a0b7aa445b69f6647300db666c96070911245cdf..6ffa53e4a78542061924c4d3cd260dea3c67d622 100644 (file)
@@ -172,6 +172,23 @@ rm -f core core.* *.core])
 AC_MSG_RESULT($sudo_cv_func_fnmatch)
 AS_IF([test $sudo_cv_func_fnmatch = yes], [$1], [$2])])
 
+dnl
+dnl Attempt to check for working PIE support.
+dnl This is a bit of a hack but on Solaris 10 with GNU ld and GNU as
+dnl we can end up with strange values from malloc().
+dnl A better check would be to verify that ASLR works with PIE.
+dnl
+AC_DEFUN([SUDO_WORKING_PIE],
+[AC_MSG_CHECKING([for working PIE support])
+AC_CACHE_VAL(sudo_cv_working_pie,
+[rm -f conftestdata; > conftestdata
+AC_RUN_IFELSE([AC_LANG_SOURCE([AC_INCLUDES_DEFAULT
+main() { char *p = malloc(1024); if (p == NULL) return 1; memset(p, 0, 1024); return 0; }])], [sudo_cv_working_pie=yes], [sudo_cv_working_pie=no],
+  [sudo_cv_working_pie=no])
+rm -f core core.* *.core])
+AC_MSG_RESULT($sudo_cv_working_pie)
+AS_IF([test $sudo_cv_working_pie = yes], [$1], [$2])])
+
 dnl
 dnl check for isblank(3)
 dnl
index 3fae65685d2aec9a39fe1c83203b86fde3e6a7b0..d6bc4749e80c3bd1b9b5355e0cad94d8ed230832 100755 (executable)
--- a/configure
+++ b/configure
@@ -1557,8 +1557,7 @@ Optional Features:
   --enable-werror         Whether to enable the -Werror compiler option
   --disable-hardening     Do not use compiler/linker exploit mitigation
                           options
-  --disable-pie           Do not build position independent executables, even
-                          if the compiler/linker supports them
+  --enable-pie            Build sudo as a position independent executable.
   --enable-admin-flag     Whether to create a Ubuntu-style admin flag file
   --enable-gss-krb5-ccache-name
                           Use GSS-API to set the Kerberos V cred cache name
@@ -5631,8 +5630,6 @@ fi
 # Check whether --enable-pie was given.
 if test "${enable_pie+set}" = set; then :
   enableval=$enable_pie;
-else
-  enable_pie=yes
 fi
 
 
@@ -14423,11 +14420,6 @@ done
                CHECKSHADOW="false"
                test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
                : ${with_logincap='maybe'}
-               # PIE is broken on FreeBSD/ia64
-               case "$host_cpu" in
-               ia64*)
-                       enable_pie=no;;
-               esac
                ;;
     *-*-*openbsd*)
                # OpenBSD has a real setreuid(2) starting with 3.3 but
@@ -20040,8 +20032,100 @@ done
 
 fi
 
-if test "$enable_pie" != "no" -a -n "$GCC"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fPIE" >&5
+
+ac_c_werror_flag=yes
+
+if test -n "$GCC"; then
+    if test -z "$enable_pie"; then
+       case "$host_os" in
+           linux*)
+               # Attempt to build with PIE support
+               enable_pie="maybe"
+               ;;
+       esac
+    fi
+    if test -n "$enable_pie"; then
+       if test "$enable_pie" = "no"; then
+           { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fno-pie" >&5
+$as_echo_n "checking whether C compiler accepts -fno-pie... " >&6; }
+if ${ax_cv_check_cflags___fno_pie+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$CFLAGS
+  CFLAGS="$CFLAGS  -fno-pie"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ax_cv_check_cflags___fno_pie=yes
+else
+  ax_cv_check_cflags___fno_pie=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  CFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_pie" >&5
+$as_echo "$ax_cv_check_cflags___fno_pie" >&6; }
+if test x"$ax_cv_check_cflags___fno_pie" = xyes; then :
+
+               _CFLAGS="$CFLAGS"
+               CFLAGS="$CFLAGS -fno-pie"
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -nopie" >&5
+$as_echo_n "checking whether the linker accepts -nopie... " >&6; }
+if ${ax_cv_check_ldflags___nopie+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+  ax_check_save_flags=$LDFLAGS
+  LDFLAGS="$LDFLAGS  -nopie"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ax_cv_check_ldflags___nopie=yes
+else
+  ax_cv_check_ldflags___nopie=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$ax_check_save_flags
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___nopie" >&5
+$as_echo "$ax_cv_check_ldflags___nopie" >&6; }
+if test x"$ax_cv_check_ldflags___nopie" = xyes; then :
+
+                   PIE_CFLAGS="-fno-pie"
+                   PIE_LDFLAGS="-nopie"
+
+else
+  :
+fi
+
+               CFLAGS="$_CFLAGS"
+
+else
+  :
+fi
+
+       else
+           { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fPIE" >&5
 $as_echo_n "checking whether C compiler accepts -fPIE... " >&6; }
 if ${ax_cv_check_cflags___fPIE+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -20072,9 +20156,9 @@ fi
 $as_echo "$ax_cv_check_cflags___fPIE" >&6; }
 if test x"$ax_cv_check_cflags___fPIE" = xyes; then :
 
-       _CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS -fPIE"
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -pie" >&5
+               _CFLAGS="$CFLAGS"
+               CFLAGS="$CFLAGS -fPIE"
+               { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the linker accepts -pie" >&5
 $as_echo_n "checking whether the linker accepts -pie... " >&6; }
 if ${ax_cv_check_ldflags___pie+:} false; then :
   $as_echo_n "(cached) " >&6
 $as_echo "$ax_cv_check_ldflags___pie" >&6; }
 if test x"$ax_cv_check_ldflags___pie" = xyes; then :
 
-           PIE_CFLAGS="-fPIE"
-           PIE_LDFLAGS="-pie"
+                   if test "$enable_pie" = "maybe"; then
+                       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working PIE support" >&5
+$as_echo_n "checking for working PIE support... " >&6; }
+if ${sudo_cv_working_pie+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f conftestdata; > conftestdata
+if test "$cross_compiling" = yes; then :
+  sudo_cv_working_pie=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+main() { char *p = malloc(1024); if (p == NULL) return 1; memset(p, 0, 1024); return 0; }
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  sudo_cv_working_pie=yes
+else
+  sudo_cv_working_pie=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+rm -f core core.* *.core
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $sudo_cv_working_pie" >&5
+$as_echo "$sudo_cv_working_pie" >&6; }
+if test $sudo_cv_working_pie = yes; then :
+  enable_pie=yes
+fi
+                   fi
+                   if test "$enable_pie" = "yes"; then
+                       PIE_CFLAGS="-fPIE"
+                       PIE_LDFLAGS="-fPIE -pie"
+                   fi
 
 else
   :
 fi
 
-       CFLAGS="$_CFLAGS"
+               CFLAGS="$_CFLAGS"
 
 else
   :
 fi
 
+       fi
+    fi
 fi
 
 if test "$enable_hardening" != "no"; then
-
-ac_c_werror_flag=yes
     if test -n "$GCC"; then
        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fstack-protector-all" >&5
 $as_echo_n "checking whether C compiler accepts -fstack-protector-all... " >&6; }
index 2191f6a038a3f8078fca4b0c99db2571d8107abf..a4cc98c2799aa41754b62c6a817f1a23877d49ea 100644 (file)
@@ -1339,8 +1339,7 @@ AC_ARG_ENABLE(hardening,
 [], [enable_hardening=yes])
 
 AC_ARG_ENABLE(pie,
-[AS_HELP_STRING([--disable-pie], [Do not build position independent executables, even if the compiler/linker supports them])],
-[], [enable_pie=yes])
+[AS_HELP_STRING([--enable-pie], [Build sudo as a position independent executable.])])
 
 AC_ARG_ENABLE(admin-flag,
 [AS_HELP_STRING([--enable-admin-flag], [Whether to create a Ubuntu-style admin flag file])],
@@ -1827,11 +1826,6 @@ case "$host" in
                CHECKSHADOW="false"
                test -z "$with_pam" && AUTH_EXCL_DEF="PAM"
                : ${with_logincap='maybe'}
-               # PIE is broken on FreeBSD/ia64
-               case "$host_cpu" in
-               ia64*)
-                       enable_pie=no;;
-               esac
                ;;
     *-*-*openbsd*)
                # OpenBSD has a real setreuid(2) starting with 3.3 but
@@ -3030,20 +3024,54 @@ if test "${with_iologdir-yes}" != "no"; then
     ])
 fi
 
+dnl
+dnl Turn warnings into errors.
+dnl All compiler/loader tests after this point will fail if
+dnl a warning is displayed (nornally, warnings are not fata).
+dnl
+AC_LANG_WERROR
+
 dnl
 dnl Check for PIE executable support if using gcc.
 dnl This test relies on AC_LANG_WERROR
 dnl
-if test "$enable_pie" != "no" -a -n "$GCC"; then
-    AX_CHECK_COMPILE_FLAG([-fPIE], [
-       _CFLAGS="$CFLAGS"
-       CFLAGS="$CFLAGS -fPIE"
-       AX_CHECK_LINK_FLAG([-pie], [
-           PIE_CFLAGS="-fPIE"
-           PIE_LDFLAGS="-pie"
-       ])
-       CFLAGS="$_CFLAGS"
-    ])
+if test -n "$GCC"; then
+    if test -z "$enable_pie"; then
+       case "$host_os" in
+           linux*)
+               # Attempt to build with PIE support
+               enable_pie="maybe"
+               ;;
+       esac
+    fi
+    if test -n "$enable_pie"; then
+       if test "$enable_pie" = "no"; then
+           AX_CHECK_COMPILE_FLAG([-fno-pie], [
+               _CFLAGS="$CFLAGS"
+               CFLAGS="$CFLAGS -fno-pie"
+               AX_CHECK_LINK_FLAG([-nopie], [
+                   PIE_CFLAGS="-fno-pie"
+                   PIE_LDFLAGS="-nopie"
+               ])
+               CFLAGS="$_CFLAGS"
+           ])
+       else
+           AX_CHECK_COMPILE_FLAG([-fPIE], [
+               _CFLAGS="$CFLAGS"
+               CFLAGS="$CFLAGS -fPIE"
+               AX_CHECK_LINK_FLAG([-pie], [
+                   if test "$enable_pie" = "maybe"; then
+                       SUDO_WORKING_PIE([enable_pie=yes], [])
+                   fi
+                   if test "$enable_pie" = "yes"; then
+                       PIE_CFLAGS="-fPIE"
+                       PIE_LDFLAGS="-fPIE -pie"
+                   fi
+               ])
+               CFLAGS="$_CFLAGS"
+           ])
+       fi
+    fi
 fi
 
 dnl
@@ -3052,7 +3080,6 @@ dnl This must be towards the end as it turns warnings
 dnl into fatal errors (and there is no way to undo that)
 dnl
 if test "$enable_hardening" != "no"; then
-    AC_LANG_WERROR
     if test -n "$GCC"; then
        AX_CHECK_COMPILE_FLAG([-fstack-protector-all], [
            AX_CHECK_LINK_FLAG([-fstack-protector-all], [