OpenBSD Journal

Developer Blog: Large Piece of PIE

Contributed by ray on from the secure-pie-operating-system dept.

Kurt Miller (kurt@) writes,

PIE support changes were committed recently to gcc, csu and gdb.

  • gcc: to add -fpie/-fPIE and -pie arguments
  • csu: to compile the C Start Up objects position independent
  • gdb: to add PIE debugging support
These changes build on top of prior work that enhanced ld.so to grok PIE, kernel changes to recognize and load PIE binaries, converting csu asm to be pic compatible and ld.so bug fixes for some relocations.

PIE stands for Position Independent Executable. It is another address space randomization technique that compiles & links executables to be position independent. When combined with a kernel that can recognize it is loading a PIE binary, the kernel can load it into a random address instead of the traditional fixed addresses programs use. By using at random load addresses it stops return-to-libc type attacks against functions in the main program.

What was recently committed are the parts needed to use PIE when the proper gcc arguments are given. It is not on by default (yet) and nothing in the tree is being linked with PIE. Work is continuing to round out the missing parts so that it can be turned on by default in the future. However, things are working for dynamically linked programs; to use it, just add the appropriate gcc arguments (more details below).

If you are interested in knowing all the gory details of how PIE was implemented on OpenBSD, take a look at my presentation or go to DCBSDCon in February where I hope to do the talk again. Instead of going over that stuff again here, let's take a look at how to use PIE.

New arguments were added to gcc to support PIE (-fpie/-fPIE and -pie). -fpie/-fPIE are similar to the gcc arguments -fpic/-fPIC in that they both create position independent objects files. However the PIE versions have one additional optimization that makes the resulting objects not suitable for shared libraries. The optimization is explained in detail in my presentation.

The -pie argument tells gcc to pass along the pie argument to the linker which understands how to build a PIE binary. When you execute the PIE binary, the kernel recognizes it and loads it at a random address. You can see the random load address by using ldd(1) or for long running processes procmap(1). For example on i386:

$ cc -c -fpie hello.c -o hello.o
$ cc -pie hello.o -o hello
$ ldd hello
hello:
       Start    End      Type Open Ref GrpRef Name
       142cc000 342d0000 exe  1    0   0      hello
       04774000 247a9000 rlib 0    1   0      /usr/lib/libc.so.49.0
       097e8000 097e8000 rtld 0    1   0      /usr/libexec/ld.so
$ ldd hello
hello:
       Start    End      Type Open Ref GrpRef Name
       1aecb000 3aecf000 exe  1    0   0      hello
       0a0c4000 2a0f9000 rlib 0    1   0      /usr/lib/libc.so.49.0
       06c3d000 06c3d000 rtld 0    1   0      /usr/libexec/ld.so
$ ldd hello
hello:
       Start    End      Type Open Ref GrpRef Name
       1a561000 3a565000 exe  1    0   0      hello
       0b8e3000 2b918000 rlib 0    1   0      /usr/lib/libc.so.49.0
       06e61000 06e61000 rtld 0    1   0      /usr/libexec/ld.so

Note that you can't just put -fpie -pie into CFLAGS since these arguments are only for the objects that get linked into a program. If you use them on a shared lib you will end up with broken shared libraries.

gdb works with PIE programs, but not with core files generated from a PIE program. So you can use gdb to attach to a running PIE program or run a PIE program in gdb, but postmortem debugging of cores isn't working yet. This is one of the things that needs to be worked on for better supporting PIE.

Another area that needs work is static PIE programs. Currently -pie -static is disabled because the resulting binary is not quite a static program. It still needs ld.so to run which means it can't be run in single user mode too.

While I've been the primary developer moving this along, I couldn't have accomplished it without the help, guidance and reviews of drahn@, kettenis@, miod@, weingart@ and other developers who gave me access to hardware or tested my diffs. Thank them for putting up with my silly PIE diff names too.

Thanks Kurt for all the hard work baking the PIE diffs, and also for this write up!

(Comments are closed)


Comments
  1. By Anonymous Coward (82.82.69.141) on

    ++kurt;

  2. By Ted Walther (70.71.225.48) on http://reactor-core.org

    Great! Is this support going to be added to pcc too?

    Comments
    1. By Kurt Miller (2001:4830:120b:1:212:f0ff:feb5:f46c) on

      > Great! Is this support going to be added to pcc too?

      It should be easy to get minimal pie support into pcc by just making -fpie /-fPIE to be the same as -fpic/-fPIC.

      Comments
      1. By Anonymous Coward (2a01:198:25d:0:20a:e4ff:fe32:17b2) on

        > It should be easy to get minimal pie support into pcc by just making
        > -fpie /-fPIE to be the same as -fpic/-fPIC.

        pcc doesn't do PIC.

        Comments
        1. By tedu (udet) on

          > > It should be easy to get minimal pie support into pcc by just making
          > > -fpie /-fPIE to be the same as -fpic/-fPIC.
          >
          > pcc doesn't do PIC.

          It also doesn't support any targets that require it, so it's pretty moot.

          Comments
          1. By Anonymous Coward (88.217.158.50) on

            > > > It should be easy to get minimal pie support into pcc by just making
            > > > -fpie /-fPIE to be the same as -fpic/-fPIC.
            > >
            > > pcc doesn't do PIC.
            >
            > It also doesn't support any targets that require it, so it's pretty moot.

            pcc supports pic on i386 that also requires it.

            Comments
            1. By tedu (udet) on

              > > > > It should be easy to get minimal pie support into pcc by just making
              > > > > -fpie /-fPIE to be the same as -fpic/-fPIC.
              > > >
              > > > pcc doesn't do PIC.
              > >
              > > It also doesn't support any targets that require it, so it's pretty moot.
              >
              > pcc supports pic on i386 that also requires it.

              i386 requires PIC? As far as I know, PIC is just the same as pic on i386.

  3. By Anonymous Coward (212.27.60.48) on

    PIE is so sloooow it will make your shiny new Core i7 act like an old 486SX.

    Comments
    1. By Daniel Gracia (paladdin) on http://www.alpuntodesal.com

      > PIE is so sloooow it will make your shiny new Core i7 act like an old 486SX.

      Well, as far as Core i7 doesn't support ECC memory, I suspect nobody cares how slow it would be with a OpenBSD/PIE combo.

      Just kidding; make some test and you'll notice PIE it not such a stopper. There's raw speed, and then security: choose your path ;)

    2. By Kurt Miller (2001:4830:120b:1:212:f0ff:feb5:f46c) on

      > PIE is so sloooow it will make your shiny new Core i7 act like an old 486SX.

      Its not all that bad, but I've not done performance measurements yet. You loose a register when compiling pic and non-local globals are via GOT/PLT.
      The impact depends on the arch. I think you will find it is quite a small hit in performance but time will tell.

  4. By Anonymous Coward (128.171.90.200) on

    Mmmmmmmm ..... pie

    Oops sorry .... I meant ...

    Mmmmmmmm ..... pi

    Sorry .... I did it again, I meant ...

    Mmmmmmmm ..... PIE

    Comments
    1. By Anonymous Coward (76.121.21.10) on

      Digg is that way --->

      Comments
      1. By Anonymous Coward (128.171.90.200) on

        You don't like pie ?

Credits

Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original deadly.org with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]