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

Re: DEB_BUILD_MAINT_OPTIONS=hardening=+pie breaks shared library builds



On 05/21/2016 07:32 PM, Theodore Ts'o wrote:
> If the pie hardening option is enabled, then dpkg-buildflags --get
> LDFLAGS emits:
> 
> 	-fPIE -pie -Wl,-z,relro
> 
> According to the dpkg-buildflags man page:
> 
>        LDFLAGS
>               Options passed to  the  compiler  when  linking  executables  or
>               shared objects
> 
> Unfortunate the linker will blow up if -fPIE is specified:
> 
> (cd elfshared; gcc --shared -o libcom_err.so.2.1 \
> 	-L../../../lib -fPIE -pie -Wl,-z,relro \
> 	-Wl,-soname,libcom_err.so.2 error_message.o et_name.o init_et.o com_err.o com_right.o -lpthread)
> /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
> (.text+0x20): undefined reference to `main'
> collect2: error: ld returned 1 exit status

Libtool filters -fPIE, -pie and -fpie when compiling shared libraries,
so anything using autotools + libtool should automatically be covered.

In a project where I have just a plain Makefile, I have used the
following in the past:

CFLAGS_LIB = $(filter-out -fPIE -fpie -pie,$(CFLAGS)) -fPIC
LDFLAGS_LIB = $(filter-out -fPIE -fpie -pie,$(LDFLAGS)) -fPIC

Unfortunately, you then also have to override the rules for the
object files that will be added to the library. In my case, this
is just a single file, but in other projects this becomes more
complicated.

However, I just looked at what CMake does, and it will not filter out
-fPIE or -pie or the such, but what it will do is the following:

 - pass -fPIC after CFLAGS & CPPFLAGS when compiling

       e.g. cc -Wall ... -fPIE -fPIC -o bla.o -c bla.c
               ^^^^^^^^^^^^^^^  ^^^^
                  C{,PP}FLAGS   added via rule

   -fPIC overrides the previous -fPIE

 - pass -shared after CFLAGS & LDFLAGS,

       e.g. cc -fPIE -pie -shared -Wl,-soname,libbla.so.0 -o libbla.so.0 bla.o -lfoo
               ^^^^^ ^^^^  ^^^^^^                                              ^^^^^
                 |    |       |                                                LDLIBS
                /   LDFLAGS   |
           CFLAGS          added via rule

Here, -shared (create shared library) will override -pie (create
executable) and the library will be compiled in the right way.

So what you could do is just make sure that all your Makefile rules
always keep -shared (when linking) and -fPIC (when compiling)
afteer CFLAGS/CPPFLAGS/LDFLAGS, and then you should be all set.

(Hopefully.)

Note that if you compile statically linked programs, you still need
to explicitly drop the -pie at the moment (-fPIE for compilation is
fine, because you can link -fPIE code into a non-PIE executable, it
just makes the code slightly larger and slower), because no libc
supports creating statically linked PIE executables as of now.
(Although dietlibc upstream is working on that at least on amd64.)

Hope that helps.

Regards,
Christian

Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: