2

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

niry
  • 3,238
  • 22
  • 34
  • 2
    I am guessing it might want to create a PIE by default? Although according to gcc.godbolt.org, that's not the case. Anyway, you might want to try adding `-fno-PIE`, and also maybe compile a different test program that works and see if the output is PIE or not. – Jester Oct 25 '16 at 17:38
  • Thank you, -no-pie when linking did it. – niry Oct 25 '16 at 18:35
  • Where does this problem come from ? I had this problem by upgrading my system... – Saroupille Nov 21 '16 at 15:08
  • 1
    @Saroupille, please see update below. I'm guessing that other distros are doing the same. – niry Nov 21 '16 at 19:18

1 Answers1

3

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.

niry
  • 3,238
  • 22
  • 34