Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sun, 02 Dec 2018 17:20:15 +0000
From: argante <argante@...me>
To: "musl@...ts.openwall.com" <musl@...ts.openwall.com>
Subject: Re: static linking problem

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Sunday, 2 December 2018 01:18, Rich Felker <dalias@...c.org> wrote:

> On Sat, Dec 01, 2018 at 10:07:53PM +0000, argante wrote:
> This does not indicate that the program is dynamic-linked, just that
> it's PIE. Use readelf -l and look for INTERP. If it's present, the
> program is dynamic linked. If it's absent, the program is static
> linked.
>

> > ldd a.out
> >
> > ==========
> >
> > ldd (0x7fb6c936f000)
>
> Is this the musl ldd? I believe it will do this or similar, and that's
> a known bug or at least limitation. It should report that the program
> is not dynamic-linked.
>

> > /lib/ld-musl-x86_64.so.1 (0x7ff0dca25000)
> > libc.so => /lib/ld-musl-x86_64.so.1 (0x7ff0dca25000)
>
> This is dynamic-linked, yes. But there's nothing wrong with your
> static-linked program. If you really don't want pie, use -no-pie or a
> toolchain that wasn't built to produce pie by default (gcc's
> --enable-default-pie option at configure time).
>
> Rich


Rich, thank you for your help.


I did everything step by step from scratch. Maybe it's a long mail, but shows stages and results.


I have a basic tool (make, cp, rm, sed etc.) and musl-cross toolchain in /cross dir (plus symlinks in cross/bin).

# ls /cross/
bin  include  lib  libexec  share  x86_64-linux-musl

# # cp libc.so from /cross/x86_64-linux-musl/lib/ to /lib
# ls -l /lib/
lrwxrwxrwx    1 root     root           12 Dec  2 09:11 ld-musl-x86_64.so.1 -> /lib/libc.so
-rwxr-xr-x    1 root     root       740888 Dec  2 09:10 libc.so


I also prepared simple scripts in /usr/ports:

# ls /usr/ports/
binutils  gcc  gmp  mpc  mpfr  musl


MUSL
----
# cd /usr/ports/musl/
# ls
build.sh  musl-1.1.20.tar.gz
# cat build.sh
#!/bin/sh
name=$(basename $(pwd))
version="1.1.20"
rm -rf $name-$version
tar zxf $name-$version.tar.gz
cd $name-$version

./configure \
	--bindir/usr/bin \
	--includedir=/usr/include \
	--syslibdir=/lib \
	--libdir=/lib \
	--enable-gcc-wrapper \
	--disable-debug \
	--enable-optimize \
	|| exit 1

make || exit 1
make install || exit 1
cd .. && rm -rf $name-$version

# ./build.sh
# ls -l /lib/
-rw-r--r--    1 root     root         1624 Dec  2 11:48 Scrt1.o
-rw-r--r--    1 root     root         1576 Dec  2 11:48 crt1.o
-rw-r--r--    1 root     root         1016 Dec  2 11:48 crti.o
-rw-r--r--    1 root     root          960 Dec  2 11:48 crtn.o
lrwxrwxrwx    1 root     root           12 Dec  2 09:11 ld-musl-x86_64.so.1 -> /lib/libc.so
-rw-r--r--    1 root     root      2573588 Dec  2 11:48 libc.a
-rwxr-xr-x    1 root     root       737368 Dec  2 11:48 libc.so
-rw-r--r--    1 root     root            8 Dec  2 11:48 libcrypt.a
-rw-r--r--    1 root     root            8 Dec  2 11:48 libdl.a
-rw-r--r--    1 root     root            8 Dec  2 11:48 libm.a
-rw-r--r--    1 root     root            8 Dec  2 11:48 libpthread.a
-rw-r--r--    1 root     root            8 Dec  2 11:48 libresolv.a
-rw-r--r--    1 root     root            8 Dec  2 11:48 librt.a
-rw-r--r--    1 root     root            8 Dec  2 11:48 libutil.a
-rw-r--r--    1 root     root            8 Dec  2 11:48 libxnet.a
-rw-r--r--    1 root     root          539 Dec  2 11:48 musl-gcc.specs
-rw-r--r--    1 root     root         2192 Dec  2 11:48 rcrt1.o

# /lib/ld-musl-x86_64.so.1
musl libc (x86_64)
Version 1.1.20
Dynamic Program Loader
Usage: /lib/ld-musl-x86_64.so.1 [options] [--] pathname [args]


GMP
---
# ls
build.sh  gmp-6.1.2.tar.gz
# cat build.sh
#!/bin/sh
name=$(basename $(pwd))
version="6.1.2"
rm -rf $name-$version
tar zxfp $name-$version.tar.gz
cd $name-$version || exit 1

./configure \
	--disable-shared || exit 1

make || exit 1
make install || exit 1
cd .. && rm -rf $name-$version

MPFR
----
#!/bin/sh
name=$(basename $(pwd))
version="3.1.4"
rm -rf $name-$version
tar zxfp $name-$version.tar.gz
cd $name-$version || exit 1

CFLAGS="-I/usr/local/include" \
LDFLAGS="-L/usr/local/lib" \
./configure \
	--disable-shared || exit 1

make || exit 1
make install || exit 1
cd .. && rm -rf $name-$version

MPC
---
#!/bin/sh
name=$(basename $(pwd))
version="1.0.3"
rm -rf $name-$version
tar zxfp $name-$version.tar.gz
cd $name-$version || exit 1

CFLAGS="-I/usr/local/include" \
LDFLAGS="-L/usr/local/lib" \
./configure \
	--disable-shared || exit 1

make || exit 1
make install || exit 1
cd .. && rm -rf $name-$version


BINUTILS
--------
I suppose it could be a problem with ld. In this test I used patches from Alpine:

https://git.alpinelinux.org/cgit/aports/tree/main/binutils

# ls
binutils-2.31.1.tar.gz                x86-Add-a-GNU_PROPERTY_X86_ISA_1_USED-note-if-needed.patch
binutils-ld-fix-static-linking.patch  x86-Properly-add-X86_ISA_1_NEEDED-property.patch
build.sh                              x86-Properly-merge-GNU_PROPERTY_X86_ISA_1_USED.patch

# cat build.sh
#!/bin/sh
name=$(basename $(pwd))
version="2.31.1"
rm -rf $name-$version
tar zxfp $name-$version.tar.gz
cd $name-$version || exit 1

patch -p1 -i ../binutils-ld-fix-static-linking.patch
patch -p1 -i ../x86-Add-a-GNU_PROPERTY_X86_ISA_1_USED-note-if-needed.patch
patch -p1 -i ../x86-Properly-add-X86_ISA_1_NEEDED-property.patch
patch -p1 -i ../x86-Properly-merge-GNU_PROPERTY_X86_ISA_1_USED.patch

./configure \
	--disable-shared \
	--disable-static \
	--disable-nls \
	--disable-install-libiberty \
	--enable-threads \
	--disable-obsolete \
	--enable-lto \
	--enable-plugins \
	--disable-multilib

make || exit 1
make install || exit 1
cd .. && rm -rf $name-$version


GCC
---
# ls
0001-ssp_nonshared.diff                                    0010-static-pie-support.diff
0002-posix_memalign.diff                                   0011-j2.diff
0003-cilkrts.diff                                          0012-s390x-muslldso.diff
0004-libatomic-test-fix.diff                               0013-microblaze-pr65649.diff
0005-libgomp-test-fix.diff                                 0014-ldbl128-config.diff
0006-libitm-test-fix.diff                                  0015-m68k.diff
0007-libvtv-test-fix.diff                                  0016-invalid_tls_model.diff
0008-Revert-PR-driver-81523-Make-static-override-pie.diff  build.sh
0009-Revert-RS6000-linux-startfile-endfile.diff            gcc-7.3.0.tar.gz

# cat build.sh
#!/bin/sh

version="7.3.0"

rm -rf gcc-$version
tar zxfvp gcc-${version}.tar.gz || exit 1

cd gcc-${version}

patch -p1 -i ../0001-ssp_nonshared.diff
patch -p1 -i ../0002-posix_memalign.diff
#patch -p1 -i ../0003-cilkrts.diff
patch -p1 -i ../0004-libatomic-test-fix.diff
patch -p1 -i ../0005-libgomp-test-fix.diff
patch -p1 -i ../0006-libitm-test-fix.diff
patch -p1 -i ../0007-libvtv-test-fix.diff
patch -p1 -i ../0008-Revert-PR-driver-81523-Make-static-override-pie.diff
patch -p1 -i ../0009-Revert-RS6000-linux-startfile-endfile.diff
patch -p1 -i ../0010-static-pie-support.diff
patch -p1 -i ../0011-j2.diff
patch -p1 -i ../0012-s390x-muslldso.diff
patch -p1 -i ../0013-microblaze-pr65649.diff
patch -p1 -i ../0014-ldbl128-config.diff
patch -p1 -i ../0015-m68k.diff
patch -p1 -i ../0016-invalid_tls_model.diff

./configure \
	CFLAGS="-Os -g0" \
	CXXFLAGS="${CFLAGS}" \
	--enable-languages=c,c++ \
	--disable-nls \
	--disable-multilib \
	--disable-werror \
	--disable-libmudflap \
	--disable-libsanitizer \
	--disable-gnu-indirect-function \
	--disable-libmpx \
	--disable-libssp \
	--disable-symver \
	--disable-libgomp \
	--disable-fixed-point \
	--enable-tls \
	--enable-deterministic-archives \
	--enable-__cxa_atexit \
	--enable-default-pie \
	--build=x86_64-linux-musl \
	--with-mpc=/usr/local

make -j4 || exit 1
make install || exit 1
cd .. && rm -rf gcc-$version

# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/x86_64-linux-musl/7.3.0/lto-wrapper
Target: x86_64-linux-musl
Configured with: ./configure CFLAGS='-Os -g0' CXXFLAGS= --enable-languages=c,c++ --disable-nls --disable-multilib --disable-werror --disable-libmudflap --disable-libsanitizer --disable-gnu-indirect-function --disable-libmpx --disable-libssp --disable-symver --disable-libgomp --disable-fixed-point --enable-tls --enable-deterministic-archives --enable-__cxa_atexit --enable-default-pie --build=x86_64-linux-musl --with-mpc=/usr/local
Thread model: posix
gcc version 7.3.0 (GCC)





tests:
======

# cat test.c
#include <stdio.h>
int main() { printf("hello..\n"); return 0; }



1. musl-cross gcc
-----------------

# gcc -static test.c
# ldd a.out
ldd: a.out: Not a valid dynamic program

# gcc -static -fpie test.c
# ldd a.out
ldd: a.out: Not a valid dynamic program

# readelf -l a.out

Elf file type is EXEC (Executable file)
Entry point 0x400154
There are 4 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x0000000000000f0c 0x0000000000000f0c  R E    200000
  LOAD           0x0000000000000fe0 0x0000000000600fe0 0x0000000000600fe0
                 0x0000000000000128 0x0000000000000838  RW     200000
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     10
  GNU_RELRO      0x0000000000000fe0 0x0000000000600fe0 0x0000000000600fe0
                 0x0000000000000020 0x0000000000000020  R      1

 Section to Segment mapping:
  Segment Sections...
   00     .init .text .fini .rodata .eh_frame
   01     .ctors .dtors .data .bss
   02
   03     .ctors .dtors





2. New toolchain
----------------

# gcc test.c
# ldd a.out
	/lib/ld-musl-x86_64.so.1 (0x7f342831a000)
	libc.so => /lib/ld-musl-x86_64.so.1 (0x7f342831a000)


# gcc -static test.c
/usr/local/bin/ld: /lib/libc.a(__libc_start_main.o): relocation R_X86_64_32 against `.rodata.__init_libc.str1.1' can not be used when making a PIE object; recompile with -fPIC
/usr/local/bin/ld: /lib/libc.a(exit.o): relocation R_X86_64_32 against undefined hidden symbol `__fini_array_end' can not be used when making a PIE object
/usr/local/bin/ld: /lib/libc.a(puts.o): relocation R_X86_64_32 against hidden symbol `__stdout_FILE' can not be used when making a PIE object
/usr/local/bin/ld: /lib/libc.a(__init_tls.o): relocation R_X86_64_32S against undefined hidden symbol `__libc' can not be used when making a PIE object
/usr/local/bin/ld: /lib/libc.a(__stdout_write.o): relocation R_X86_64_32S against hidden symbol `__stdio_write' can not be used when making a PIE object
/usr/local/bin/ld: /lib/libc.a(ofl.o): relocation R_X86_64_32 against `.bss.ofl_lock' can not be used when making a PIE object; recompile with -fPIC
/usr/local/bin/ld: final link failed: nonrepresentable section on output
collect2: error: ld returned 1 exit status




I recompiled musl (with a new compiler), and now:


# gcc -static -fno-pie test.c
/usr/local/bin/ld: /tmp/ccJKiFnE.o: relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIC
/usr/local/bin/ld: final link failed: nonrepresentable section on output
collect2: error: ld returned 1 exit status


# gcc -static test.c
# ldd a.out
	ldd (0x7f76e24c3000)

# ls -lh /usr/bin/ldd
lrwxrwxrwx    1 root     root           12 Dec  2 11:26 /usr/bin/ldd -> /lib/libc.so


# readelf -l a.out

Elf file type is DYN (Shared object file)
Entry point 0x1062
There are 7 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000308 0x0000000000000308  R      0x1000
  LOAD           0x0000000000001000 0x0000000000001000 0x0000000000001000
                 0x0000000000000f7f 0x0000000000000f7f  R E    0x1000
  LOAD           0x0000000000002000 0x0000000000002000 0x0000000000002000
                 0x0000000000000094 0x0000000000000094  R      0x1000
  LOAD           0x0000000000002e58 0x0000000000003e58 0x0000000000003e58
                 0x00000000000002d8 0x00000000000009e0  RW     0x1000
  DYNAMIC        0x0000000000002e80 0x0000000000003e80 0x0000000000003e80
                 0x0000000000000150 0x0000000000000150  RW     0x8
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x0000000000002e58 0x0000000000003e58 0x0000000000003e58
                 0x00000000000001a8 0x00000000000001a8  R      0x1

 Section to Segment mapping:
  Segment Sections...
   00     .hash .gnu.hash .dynsym .dynstr .rela.dyn
   01     .init .plt .plt.got .text .fini
   02     .rodata .eh_frame
   03     .ctors .dtors .data.rel.ro .dynamic .got .got.plt .data .bss
   04     .dynamic
   05
   06     .ctors .dtors .data.rel.ro .dynamic .got




I still can't understand why musl-cross ldd works correctly, and new toolchain shows such a strange result. Did I overlook something? I even tried -Wl,--no-dynamic-linker.

Best regards



Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.