gcc 6.2.0 is attempting to create shared object wh

2019-07-19 03:16发布

问题:

With non relocatable assembler code linking was never a problem up until gcc 6.2.0. I don't know the exact version that stared this, but with gcc 5.4.0 (and below) this worked:

$ gcc -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto

However, with gcc 6.2.0:

$ gcc -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto
/usr/bin/ld: ../../../lib/libribs2_ssl.a(context_asm.o): relocation R_X86_64_32S against symbol `current_ctx' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status

Trying to force static linking creates another problem:

$ gcc -static -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto -ldl
/usr/lib/gcc/x86_64-linux-gnu/6/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
(.text+0x11): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
../obj/httpget.o: In function `main':
/home/nir/ribs2/examples/httpget/src/httpget.c:194: warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

And the program segfaults when using gethostbyname() (but works otherwise)

Also trying to mix static and dynamic doesn't work.

$ gcc -o httpget -Wl,-Bstatic ../obj/httpget.o ../../../lib/libribs2_ssl.a -Wl,-Bdynamic -lssl -lcrypto
/usr/bin/ld: ../../../lib/libribs2_ssl.a(context_asm.o): relocation R_X86_64_32S against symbol `current_ctx' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status

Any ideas? Link to the project: https://github.com/niryeffet/ribs2

回答1:

Thanks to the hint from @Jester: adding -no-pie (not -fno-PIE) to LDFLAGS solved the problem.

gcc -no-pie -o httpget ../obj/httpget.o ../../../lib/libribs2_ssl.a -lssl -lcrypto

The change also works on gcc 5.4. It seems as the default has changed.

UPDATE:

This explains it. From https://wiki.ubuntu.com/SecurityTeam/PIE

In Ubuntu 16.10, as an additional compiler hardening measure, we've enabled PIE and immediate binding by default on amd64 and ppc64le. This greatly increases the effectiveness of ASLR on those platforms.