diff mbox

[v8,1.0] configure: build position independent executables on x86-Linux hosts

Message ID 1321380737-23007-1-git-send-email-avi@redhat.com
State New
Headers show

Commit Message

Avi Kivity Nov. 15, 2011, 6:12 p.m. UTC
Change the default on x86 Linux hosts to building PIE (position
independent executables); instead of restricting the option to
user-only targets, apply it to all targets.

In addition, set the relocation sections to read-only (relro) when
available; this reduces the attack surface by disallowing changes to
relocation tables at runtime.

While PIE reduces performance and relro increases load time, it
greatly improves security, with the potential to reduce a code
execution vulnerability to a self denial of service.

Non-x86 are not changed, as they require TCG changes; neither are
non-Linux, due to lack of test coverage.

Signed-off-by: Avi Kivity <avi@redhat.com>
---

v8: restrict further to Linux hosts
    use linker option '-pie' instead of '-Wl,-pie'; fixes link on x86_64

v7: avoid 'test -a'
    optimize relro/now linker flag test
    fail if toolchain doesn't support pie while the user explicitly asked for it

v6: fix subject line. sigh.

v5: fix typos; only default enable for x86; mutually exclusive with -static

v4: say it's v4 and for 1.0

v3: detect toolchain support for PIE at configure time

v2: improve description to include relro

 configure |   65 ++++++++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 47 insertions(+), 18 deletions(-)

Comments

Avi Kivity Nov. 20, 2011, 9:11 a.m. UTC | #1
On 11/15/2011 08:12 PM, Avi Kivity wrote:
> Change the default on x86 Linux hosts to building PIE (position
> independent executables); instead of restricting the option to
> user-only targets, apply it to all targets.
>
> In addition, set the relocation sections to read-only (relro) when
> available; this reduces the attack surface by disallowing changes to
> relocation tables at runtime.
>
> While PIE reduces performance and relro increases load time, it
> greatly improves security, with the potential to reduce a code
> execution vulnerability to a self denial of service.
>
> Non-x86 are not changed, as they require TCG changes; neither are
> non-Linux, due to lack of test coverage.
>
>

Ping.
Blue Swirl Nov. 20, 2011, 5:34 p.m. UTC | #2
On Sun, Nov 20, 2011 at 09:11, Avi Kivity <avi@redhat.com> wrote:
> On 11/15/2011 08:12 PM, Avi Kivity wrote:
>> Change the default on x86 Linux hosts to building PIE (position
>> independent executables); instead of restricting the option to
>> user-only targets, apply it to all targets.
>>
>> In addition, set the relocation sections to read-only (relro) when
>> available; this reduces the attack surface by disallowing changes to
>> relocation tables at runtime.
>>
>> While PIE reduces performance and relro increases load time, it
>> greatly improves security, with the potential to reduce a code
>> execution vulnerability to a self denial of service.
>>
>> Non-x86 are not changed, as they require TCG changes; neither are
>> non-Linux, due to lack of test coverage.
>>
>>
>
> Ping.

I tested the patch on OpenBSD 5.0/Sparc64 with --enable-pie, but the
resulting executables crash immediately. Maybe the PIE binaries are
not supported by the Sparc64 kernel or ld.so, some PIE support was
added in 4.4.

It looks like the support for PIE executables was only added to GDB
7.1. For example Debian stable:

GNU gdb (GDB) 7.0.1-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Attaching to process 2092

warning: The current binary is a PIE (Position Independent Executable), which
GDB does NOT currently support.  Most debugger features will fail if used
in this session.

Reading symbols from /src/qemu/obj-amd64/i386-softmmu/qemu-system-i386...done.
0x00007f6f08ccf8d3 in ?? ()
(gdb) b do_interrupt
Cannot access memory at address 0x2136c0

Perhaps developers or users inclined to debug can be assumed to have a
recent GDB. Though on OpenBSD, GDB is pretty old 6.3.

Another issue is that this creates a point for bisection where
crossing it, all objects must be thrown away. We have a few other such
points already due to generated file name clashes so this has not been
a blocking issue.
Avi Kivity Nov. 21, 2011, 8:39 a.m. UTC | #3
On 11/20/2011 07:34 PM, Blue Swirl wrote:
> On Sun, Nov 20, 2011 at 09:11, Avi Kivity <avi@redhat.com> wrote:
> > On 11/15/2011 08:12 PM, Avi Kivity wrote:
> >> Change the default on x86 Linux hosts to building PIE (position
> >> independent executables); instead of restricting the option to
> >> user-only targets, apply it to all targets.
> >>
> >> In addition, set the relocation sections to read-only (relro) when
> >> available; this reduces the attack surface by disallowing changes to
> >> relocation tables at runtime.
> >>
> >> While PIE reduces performance and relro increases load time, it
> >> greatly improves security, with the potential to reduce a code
> >> execution vulnerability to a self denial of service.
> >>
> >> Non-x86 are not changed, as they require TCG changes; neither are
> >> non-Linux, due to lack of test coverage.
> >>
> >>
> >
> > Ping.
>
> I tested the patch on OpenBSD 5.0/Sparc64 with --enable-pie, but the
> resulting executables crash immediately. Maybe the PIE binaries are
> not supported by the Sparc64 kernel or ld.so, some PIE support was
> added in 4.4.

That's fine, we're off by default there.

> It looks like the support for PIE executables was only added to GDB
> 7.1. For example Debian stable:
>
> GNU gdb (GDB) 7.0.1-debian
> Copyright (C) 2009 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "x86_64-linux-gnu".
> For bug reporting instructions, please see:
> <http://www.gnu.org/software/gdb/bugs/>.
> Attaching to process 2092
>
> warning: The current binary is a PIE (Position Independent Executable), which
> GDB does NOT currently support.  Most debugger features will fail if used
> in this session.
>
> Reading symbols from /src/qemu/obj-amd64/i386-softmmu/qemu-system-i386...done.
> 0x00007f6f08ccf8d3 in ?? ()
> (gdb) b do_interrupt
> Cannot access memory at address 0x2136c0
>
> Perhaps developers or users inclined to debug can be assumed to have a
> recent GDB. Though on OpenBSD, GDB is pretty old 6.3.

IMO the advantages in security are greater than the disadvantages in
comfort.  You can always use --disable-pie if you find your debugger
doesn't support it, but you can't --enable-pie if you've been breached.

> Another issue is that this creates a point for bisection where
> crossing it, all objects must be thrown away. We have a few other such
> points already due to generated file name clashes so this has not been
> a blocking issue.

I'll look at adding a dependency on build flags for 1.1.
Anthony Liguori Nov. 22, 2011, 12:22 a.m. UTC | #4
On 11/15/2011 12:12 PM, Avi Kivity wrote:
> Change the default on x86 Linux hosts to building PIE (position
> independent executables); instead of restricting the option to
> user-only targets, apply it to all targets.
>
> In addition, set the relocation sections to read-only (relro) when
> available; this reduces the attack surface by disallowing changes to
> relocation tables at runtime.
>
> While PIE reduces performance and relro increases load time, it
> greatly improves security, with the potential to reduce a code
> execution vulnerability to a self denial of service.
>
> Non-x86 are not changed, as they require TCG changes; neither are
> non-Linux, due to lack of test coverage.
>
> Signed-off-by: Avi Kivity<avi@redhat.com>

Applied.  Thanks.

Regards,

Anthony Liguori

> ---
>
> v8: restrict further to Linux hosts
>      use linker option '-pie' instead of '-Wl,-pie'; fixes link on x86_64
>
> v7: avoid 'test -a'
>      optimize relro/now linker flag test
>      fail if toolchain doesn't support pie while the user explicitly asked for it
>
> v6: fix subject line. sigh.
>
> v5: fix typos; only default enable for x86; mutually exclusive with -static
>
> v4: say it's v4 and for 1.0
>
> v3: detect toolchain support for PIE at configure time
>
> v2: improve description to include relro
>
>   configure |   65 ++++++++++++++++++++++++++++++++++++++++++++----------------
>   1 files changed, 47 insertions(+), 18 deletions(-)
>
> diff --git a/configure b/configure
> index 6c77fbb..75e1f10 100755
> --- a/configure
> +++ b/configure
> @@ -172,7 +172,7 @@ aix="no"
>   blobs="yes"
>   pkgversion=""
>   check_utests=""
> -user_pie="no"
> +pie=""
>   zero_malloc=""
>   trace_backend="nop"
>   trace_file="trace"
> @@ -701,9 +701,9 @@ for opt do
>     ;;
>     --disable-guest-base) guest_base="no"
>     ;;
> -  --enable-user-pie) user_pie="yes"
> +  --enable-pie) pie="yes"
>     ;;
> -  --disable-user-pie) user_pie="no"
> +  --disable-pie) pie="no"
>     ;;
>     --enable-uname-release=*) uname_release="$optarg"
>     ;;
> @@ -1031,8 +1031,8 @@ echo "  --disable-bsd-user       disable all BSD usermode emulation targets"
>   echo "  --enable-guest-base      enable GUEST_BASE support for usermode"
>   echo "                           emulation targets"
>   echo "  --disable-guest-base     disable GUEST_BASE support"
> -echo "  --enable-user-pie        build usermode emulation targets as PIE"
> -echo "  --disable-user-pie       do not build usermode emulation targets as PIE"
> +echo "  --enable-pie             build Position Independent Executables"
> +echo "  --disable-pie            do not build Position Independent Executables"
>   echo "  --fmod-lib               path to FMOD library"
>   echo "  --fmod-inc               path to FMOD includes"
>   echo "  --oss-lib                path to OSS library"
> @@ -1099,6 +1099,47 @@ for flag in $gcc_flags; do
>       fi
>   done
>
> +if test "$static" = "yes" ; then
> +  if test "$pie" = "yes" ; then
> +    echo "static and pie are mutually incompatible"
> +    exit 1
> +  else
> +    pie="no"
> +  fi
> +fi
> +
> +if test "$pie" = ""; then
> +  case "$cpu-$targetos" in
> +    i386-Linux|x86_64-Linux)
> +      ;;
> +    *)
> +      pie="no"
> +      ;;
> +  esac
> +fi
> +
> +if test "$pie" != "no" ; then
> +  cat>  $TMPC<<  EOF
> +int main(void) { return 0; }
> +EOF
> +  if compile_prog "-fPIE -DPIE" "-pie"; then
> +    QEMU_CFLAGS="-fPIE -DPIE $QEMU_CFLAGS"
> +    LDFLAGS="-pie $LDFLAGS"
> +    pie="yes"
> +    if compile_prog "" "-Wl,-z,relro -Wl,-z,now" ; then
> +      LDFLAGS="-Wl,-z,relro -Wl,-z,now $LDFLAGS"
> +    fi
> +  else
> +    if test "$pie" = "yes"; then
> +      echo "PIE not available due to missing toolchain support"
> +      exit 1
> +    else
> +      echo "Disabling PIE due to missing toolchain support"
> +      pie="no"
> +    fi
> +  fi
> +fi
> +
>   #
>   # Solaris specific configure tool chain decisions
>   #
> @@ -2765,7 +2806,7 @@ echo "Documentation     $docs"
>   echo "uname -r          $uname_release"
>   echo "NPTL support      $nptl"
>   echo "GUEST_BASE        $guest_base"
> -echo "PIE user targets  $user_pie"
> +echo "PIE               $pie"
>   echo "vde support       $vde"
>   echo "Linux AIO support $linux_aio"
>   echo "ATTR/XATTR support $attr"
> @@ -3225,9 +3266,6 @@ for d in libdis libdis-user; do
>       symlink $source_path/Makefile.dis $d/Makefile
>       echo>  $d/config.mak
>   done
> -if test "$static" = "no" -a "$user_pie" = "yes" ; then
> -  echo "QEMU_CFLAGS+=-fpie">  libdis-user/config.mak
> -fi
>
>   for target in $target_list; do
>   target_dir="$target"
> @@ -3646,12 +3684,6 @@ if test "$target_softmmu" = "yes" ; then
>     esac
>   fi
>
> -if test "$target_user_only" = "yes" -a "$static" = "no" -a \
> -	"$user_pie" = "yes" ; then
> -  cflags="-fpie $cflags"
> -  ldflags="-pie $ldflags"
> -fi
> -
>   if test "$target_softmmu" = "yes" -a \( \
>           "$TARGET_ARCH" = "microblaze" -o \
>           "$TARGET_ARCH" = "cris" \) ; then
> @@ -3775,9 +3807,6 @@ d=libuser
>   mkdir -p $d
>   mkdir -p $d/trace
>   symlink $source_path/Makefile.user $d/Makefile
> -if test "$static" = "no" -a "$user_pie" = "yes" ; then
> -  echo "QEMU_CFLAGS+=-fpie">  $d/config.mak
> -fi
>
>   if test "$docs" = "yes" ; then
>     mkdir -p QMP
Brad Smith Nov. 29, 2011, 8:32 a.m. UTC | #5
On 20/11/11 12:34 PM, Blue Swirl wrote:
> On Sun, Nov 20, 2011 at 09:11, Avi Kivity<avi@redhat.com>  wrote:
>> On 11/15/2011 08:12 PM, Avi Kivity wrote:
>>> Change the default on x86 Linux hosts to building PIE (position
>>> independent executables); instead of restricting the option to
>>> user-only targets, apply it to all targets.
>>>
>>> In addition, set the relocation sections to read-only (relro) when
>>> available; this reduces the attack surface by disallowing changes to
>>> relocation tables at runtime.
>>>
>>> While PIE reduces performance and relro increases load time, it
>>> greatly improves security, with the potential to reduce a code
>>> execution vulnerability to a self denial of service.
>>>
>>> Non-x86 are not changed, as they require TCG changes; neither are
>>> non-Linux, due to lack of test coverage.
>>>
>>>
>>
>> Ping.
>
> I tested the patch on OpenBSD 5.0/Sparc64 with --enable-pie, but the
> resulting executables crash immediately. Maybe the PIE binaries are
> not supported by the Sparc64 kernel or ld.so, some PIE support was
> added in 4.4.

OpenBSD has had PIE support as of 4.5.

sparc64 has PIE support as does alpha/amd64/i386/powerpc/mips64/mips64el/sh.
sparc was updated from gcc2 to 4 recently so maybe it'll get PIE support
and arm/hppa suffer due to binutils bugs that need to be resolved
by a binutils update.

We build a handful of projects in our ports tree with PIE support either
because they automatically do so or we've enabled them to do so and build
with PIE support on all of the archs listed.

> It looks like the support for PIE executables was only added to GDB
> 7.1. For example Debian stable:

OpenBSD has some level of PIE support in its GDB 6.3.

CVSROOT:	/cvs
Module name:	src
Changes by:	kurt@cvs.openbsd.org	2008/11/11 15:57:48

Modified files:
	gnu/usr.bin/binutils/gdb: Makefile.in breakpoint.c breakpoint.h
	                          infrun.c objfiles.c solib-svr4.c
	                          solib.c solist.h symfile-mem.c
	                          symfile.c varobj.c varobj.h

Log message:
Enable support for debugging pie programs. Code from Elena Zannoni's
<ezannoni at redhat dot com> pie branch in gdb cvs, less extraneous
parts and with some bug fixes. Debugging w/core files for pie programs
isn't working yet since AUXV data isn't included in our core files at
the moment.

feedback and ok kettenis@

> Perhaps developers or users inclined to debug can be assumed to have a
> recent GDB. Though on OpenBSD, GDB is pretty old 6.3.

There is also newer gdb (7.2) in OpenBSD ports under devel/gdb and gdb
package and installs as egdb, although only available for non x86 archs
with -current due to a silly misfeature in the port Makefile.

> Another issue is that this creates a point for bisection where
> crossing it, all objects must be thrown away. We have a few other such
> points already due to generated file name clashes so this has not been
> a blocking issue.
diff mbox

Patch

diff --git a/configure b/configure
index 6c77fbb..75e1f10 100755
--- a/configure
+++ b/configure
@@ -172,7 +172,7 @@  aix="no"
 blobs="yes"
 pkgversion=""
 check_utests=""
-user_pie="no"
+pie=""
 zero_malloc=""
 trace_backend="nop"
 trace_file="trace"
@@ -701,9 +701,9 @@  for opt do
   ;;
   --disable-guest-base) guest_base="no"
   ;;
-  --enable-user-pie) user_pie="yes"
+  --enable-pie) pie="yes"
   ;;
-  --disable-user-pie) user_pie="no"
+  --disable-pie) pie="no"
   ;;
   --enable-uname-release=*) uname_release="$optarg"
   ;;
@@ -1031,8 +1031,8 @@  echo "  --disable-bsd-user       disable all BSD usermode emulation targets"
 echo "  --enable-guest-base      enable GUEST_BASE support for usermode"
 echo "                           emulation targets"
 echo "  --disable-guest-base     disable GUEST_BASE support"
-echo "  --enable-user-pie        build usermode emulation targets as PIE"
-echo "  --disable-user-pie       do not build usermode emulation targets as PIE"
+echo "  --enable-pie             build Position Independent Executables"
+echo "  --disable-pie            do not build Position Independent Executables"
 echo "  --fmod-lib               path to FMOD library"
 echo "  --fmod-inc               path to FMOD includes"
 echo "  --oss-lib                path to OSS library"
@@ -1099,6 +1099,47 @@  for flag in $gcc_flags; do
     fi
 done
 
+if test "$static" = "yes" ; then
+  if test "$pie" = "yes" ; then
+    echo "static and pie are mutually incompatible"
+    exit 1
+  else
+    pie="no"
+  fi
+fi
+
+if test "$pie" = ""; then
+  case "$cpu-$targetos" in
+    i386-Linux|x86_64-Linux)
+      ;;
+    *)
+      pie="no"
+      ;;
+  esac
+fi
+
+if test "$pie" != "no" ; then
+  cat > $TMPC << EOF
+int main(void) { return 0; }
+EOF
+  if compile_prog "-fPIE -DPIE" "-pie"; then
+    QEMU_CFLAGS="-fPIE -DPIE $QEMU_CFLAGS"
+    LDFLAGS="-pie $LDFLAGS"
+    pie="yes"
+    if compile_prog "" "-Wl,-z,relro -Wl,-z,now" ; then
+      LDFLAGS="-Wl,-z,relro -Wl,-z,now $LDFLAGS"
+    fi
+  else
+    if test "$pie" = "yes"; then
+      echo "PIE not available due to missing toolchain support"
+      exit 1
+    else
+      echo "Disabling PIE due to missing toolchain support"
+      pie="no"
+    fi
+  fi
+fi
+
 #
 # Solaris specific configure tool chain decisions
 #
@@ -2765,7 +2806,7 @@  echo "Documentation     $docs"
 echo "uname -r          $uname_release"
 echo "NPTL support      $nptl"
 echo "GUEST_BASE        $guest_base"
-echo "PIE user targets  $user_pie"
+echo "PIE               $pie"
 echo "vde support       $vde"
 echo "Linux AIO support $linux_aio"
 echo "ATTR/XATTR support $attr"
@@ -3225,9 +3266,6 @@  for d in libdis libdis-user; do
     symlink $source_path/Makefile.dis $d/Makefile
     echo > $d/config.mak
 done
-if test "$static" = "no" -a "$user_pie" = "yes" ; then
-  echo "QEMU_CFLAGS+=-fpie" > libdis-user/config.mak
-fi
 
 for target in $target_list; do
 target_dir="$target"
@@ -3646,12 +3684,6 @@  if test "$target_softmmu" = "yes" ; then
   esac
 fi
 
-if test "$target_user_only" = "yes" -a "$static" = "no" -a \
-	"$user_pie" = "yes" ; then
-  cflags="-fpie $cflags"
-  ldflags="-pie $ldflags"
-fi
-
 if test "$target_softmmu" = "yes" -a \( \
         "$TARGET_ARCH" = "microblaze" -o \
         "$TARGET_ARCH" = "cris" \) ; then
@@ -3775,9 +3807,6 @@  d=libuser
 mkdir -p $d
 mkdir -p $d/trace
 symlink $source_path/Makefile.user $d/Makefile
-if test "$static" = "no" -a "$user_pie" = "yes" ; then
-  echo "QEMU_CFLAGS+=-fpie" > $d/config.mak
-fi
 
 if test "$docs" = "yes" ; then
   mkdir -p QMP