JonathonReinhart / staticx

Create static executable from dynamic executable
https://staticx.readthedocs.io/
Other
319 stars 35 forks source link

Support "compat" bootloaders #55

Open JonathonReinhart opened 7 years ago

JonathonReinhart commented 7 years ago

Currently, the bootloader is built only for the native platform.

If a program is built with -m32 and runs on a native 64-bit system, there will be several problems:

$ gcc -m32 -Wall -Werror -o hello32 hello.c 
$ ./hello32
Hello, world!
$ staticx hello32 hello32.staticx
$ ./hello32.staticx 
hello32.staticx: ELF file disagrees with program header size: 0 != 56
  1. Currently all of the Elf_ structures are defined to Elf64. So the 64-bit bootloader will disagree with the 32-bit user program's ELF header.
  2. Even if that is fixed, the bootloader itself is currently always 64-bit.

To fix this we need to:

  1. Update the #defines in bootloader/elfutil.h. (Actually, we should typedef them instead. These should be defined to the 32- or 64-bit types according to the build architecture.
  2. If possible (ugh...) build both a 32- and 64- bit version of the bootloader
  3. During staticx invocation, detect whether a 32- or 64- bit application is being archived and select the appropriate bootloader flavor.

As a stop-gap measure to prevent unexpected outcomes, we could implement part of 3. and ensure that only the expected application type is being given.

JonathonReinhart commented 7 years ago
$ objdump -a hello32

hello32:     file format elf32-i386
hello32

$ objdump -a hello

hello:     file format elf64-x86-64
hello
JonathonReinhart commented 7 years ago

Alternatively, we could use pyelftools and read the file header ourselves.

JonathonReinhart commented 7 years ago

It might be difficult to match a bootloader to 32- and 64-bit applications. musl-gcc -m32 doesn't seem to work:

$ musl-gcc -m32 -Wall -Werror -o hello32-musl hello.c 
/usr/bin/ld: i386 architecture of input file `/usr/lib/gcc/x86_64-redhat-linux/6.3.1/32/crtbegin.o' is incompatible with i386:x86-64 output
/usr/bin/ld: i386 architecture of input file `/tmp/ccU3cyxZ.o' is incompatible with i386:x86-64 output
/usr/bin/ld: i386 architecture of input file `/usr/lib/gcc/x86_64-redhat-linux/6.3.1/32/crtend.o' is incompatible with i386:x86-64 output
collect2: error: ld returned 1 exit status

GCC's multilib (-m32) is built on the assumption that the same set of headers can be used. This is generally an invalid assumption, not just for libc but for third-party libraries whose headers might be in the include paths too. In principle you could hack on the gcc spec files to get it to use different include paths for different ABIs, but a dedicated cross compiler is an easier approach.

Rich

http://www.openwall.com/lists/musl/2016/10/05/18

Also:

http://www.openwall.com/lists/musl/2015/11/17/11

It appears to be possible:

Can we have musl-libc multilib?

JonathonReinhart commented 7 years ago

I tried install both the native x86_64 version and i386, but that appears to be unsupported:

# dpkg --add-architecture i386
# apt update
# apt install musl musl-dev musl-tools musl:i386 musl-dev:i386 musl-tools:i386
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 musl-dev : Conflicts: musl-dev:i386 but 0.9.15-1 is to be installed
 musl-dev:i386 : Conflicts: musl-dev but 0.9.15-1 is to be installed
 musl-tools : Depends: gcc (>= 4.7.2) but it is not going to be installed
              Conflicts: musl-tools:i386 but 0.9.15-1 is to be installed
 musl-tools:i386 : Conflicts: musl-tools but 0.9.15-1 is to be installed
E: Unable to correct problems, you have held broken packages.
JonathonReinhart commented 5 years ago

Possible solution: http://musl.cc/