[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: PIE and static libraries

On 05/22/2016 08:48 AM, Andreas Metzler wrote:
> https://lintian.debian.org/tags/hardening-no-pie.html says "It is
> unlikely to work when compiling static libraries or executables (gcc
> -static)."

For static libraries, it really depends on what you want to do with
them. A static library is just an archive of .o files (similar to
tar), nothing more, and linking against a static library is roughly
the same as just adding more .o files to the linker line. You can
also link a static library into a shared library - the code in the
static library is then just copied into the shared library (but the
code then must be compiled with -fPIC, as with all other code that
is used in shared libraries).

It's therefore in possible to generate a static library with code
that was compiled with either -fPIC or -fPIE.

The question is what you want to use the code for:

 - code compiled without -fPIC and without -fPIE can be used only
   in non-PIE executables

       => a static library containing such code may not be linked
          into a PIE executable and may not be linked into a
          shared library

 - code compiled with -fPIE can be used in any executable but not
   in shared libraries

       => if you link -fPIE code into a non-PIE executable, it
          will work. Note, however, that PIE code is slightly
          larger and slower than non-PIE code. (The difference is
          tiny on modern platforms, though, and IMHO worth it
          w.r.t. hardening.)

 - code compiled with -fPIC can be used in anything, from shared
   libraries to executables (PIE or not)

       => however, -fPIC code is again slightly slower and
          larger than -fPIE code. On the other hand, if you look
          at how much functionality of modern systems is in
          shared libs anyway, IMHO this doesn't matter as much.
          Also, gcc starting with version 5 has optimized
          performance of -fPIC even on older x86_32 quite a bit,
          see [1]. So starting with Stretch, I don't think the
          performance argument against using PIC code holds much
          water anymore, even on older platforms.

Note, however, that you cannot currently create PIE executables
(-pie LDFLAGS) that are fully statically linked (-static linker
flag). But you _can_ create executables that use PIE, are
dynamically linked binaries (i.e. uses libc.so), but which do
link against some static libraries - as long as the code in
those static libraries was compiled with either -fPIE or -fPIC.

So in the end in boils down to the following:

A. From a hardening perspective, any code that is added to
   static libraries should be compiled with -fPIE if the static
   library will only ever be used in executables, and with
   -fPIC if it also might be used in shared libraries.
   (Although, to be honest, that use case is a bit rarer.)

B. From a performance perspective, using non-PIC/PIE code is
   faster, though not necessarily by much anymore. Personally,
   I think the benefits gained from using PIE/PIC in hardening
   trump these performance considerations in a general-purpose
   distribution such as Debian anytime - but you should be
   aware of them.

Therefore, I would recommend to use at least -fPIE for static
libraries, and possibly -fPIC if you think they might be used
in other dynamic libraries.

Hope that helps.


[1] https://software.intel.com/en-us/blogs/2014/12/26/new-optimizations-for-x86-in-upcoming-gcc-50-32bit-pic-mode

Attachment: signature.asc
Description: OpenPGP digital signature

Reply to: