This is a read-only archive. Find the latest Linux articles, documentation, and answers at the new!

Feature: System Administration

Quickly move an executable between systems with ELF Statifier

By Ben Martin on October 23, 2008 (9:00:00 AM)

Share    Print    Comments   

Shared libraries that are dynamically linked make more efficient use of disk space than those that are statically linked, and more importantly allow you to perform security updates in a more efficient manner, but executables compiled against a particular version of a dynamic library expect that version of the shared library to be available on the machine they run on. If you are running machines with both Fedora 9 and openSUSE 11, the versions of some shared libraries are likely to be slightly different, and if you copy an executable between the machines, the file might fail to execute because of these version differences. With ELF Statifier you can create a statically linked version of an executable, so the executable includes the shared libraries instead of seeking them at run time. A staticly linked executable is much more likely to run on a different Linux distribution or a different version of the same distribution.

Of course, to do this you sacrifice some disk space, because the statically linked executable includes a copy of the shared libraries that it needs, but in these days of terabyte disks the space consideration is less important than the security one. Consider what happens if your executables are dynamically linked to a shared library, say libfoo, and there is a security update to libfoo. When your applications are dynamically linked you can just update the shared copy of libfoo and your applications will no longer be vulnerable to the security issue in the older libfoo. If on the other hand you have a statically linked executable, it will still include and use its own private copy of the old libfoo. You'll have to recreate the statically linked executable to get the newer libfoo and security update.

Still, there are times when you want to take a daemon you compiled on a Fedora machine and run it on your openSUSE machine without having to recompile it and all its dependencies. Sometimes you just want it to execute now and can rebuild it later if desired. Of course, the machine you copy the executable from and the one on which you want to run it must have the same architecture.

ELF Statifier is packaged as a 1-Click install for openSUSE 10.3 but not for Ubuntu Hardy or Fedora. I'll use version 1.6.14 of ELF Statifier and build it from source on a Fedora 9 x86 machine. ELF Statifier does not use autotools, so you compile by simply invoking make. Compilation and installation is shown below.

$ tar xzvf statifier-1.6.14.tar.gz $ cd ./statifier-* $ make $ sudo make install

As an example of how to use the utility, I'll create a statically linked version of the ls binary in the commands shown below. First I create a personal copy of the dynamically linked executable and inspect it to see what it dynamically links to. You run statifier with the path to the dynamically linked executable as the first argument and the path where you want to create the statically linked executable as the second argument. Notice that the ldd command reports that no dynamically linked libraries are required by ls-static. The next command shows that the binary size has grown significantly for the static version of ls.

$ mkdir test $ cd ./test $ cp -a /bin/ls ls-dynamic $ ls -lh -rwxr-xr-x 1 ben ben 112K 2008-08-01 04:05 ls-dynamic $ ldd ls-dynamic => (0x00110000) => /lib/ (0x00a3a000) => /lib/ (0x00a06000) => /lib/ (0x00d8a000) => /lib/ (0x0084e000) => /lib/ (0x009eb000) /lib/ (0x0082e000) => /lib/ (0x009e4000) => /lib/ (0x0606d000) $ statifier ls-dynamic ls-static $ ldd ls-static not a dynamic executable $ ls -lh ls-static -rwxr-x--- 1 ben ben 2.0M 2008-10-03 12:05 ls-static $ ls-static /tmp ... $ ls-static -lh Segmentation fault

As you can see above, the statified ls crashes when you run it with the -l option. If you get segmentation faults when running your statified executables you should disable stack randomization and recreate the statified executable. The stack and address space randomization feature of the Linux kernel makes the locations used for the stack and other important parts of an executable change every time it is executed. Randomizing things each time you run a binary hinders attacks such as the return-to-libc attack because the location of libc functions changes all the time.

You are giving away some security by changing the randomize_va_space parameter as shown below. The change to randomize_va_space affects not only attacks on the executables themselves but also exploit attempts that rely on buffer overflows to compromise the system. Without randomization, both attacks become more straightforward. If you set randomize_va_space to zero as shown below and recreate the ls-static binary, things should work as expected. You'll have to leave the stack randomization feature disabled in order to execute the statified executable.

# cd /proc/sys/kernel # cat randomize_va_space 2 # echo -n 0 >| randomize_va_space # cat randomize_va_space 0

There are a few other tricks up statifier's sleeve: you can set or unset environment variables for the statified executable, and include additional libraries (LD_PRELOAD libraries) into the static executable. Being able to set additional environment variables for a static executable is useful when the binary you are statifying relies on finding additional resources like configuration files. If the binary allows you to tell it where to find its resources through environment variables, you can include these settings directly into the statified executable.

The ability to include preloaded shared libraries into the statified binary (LD_PRELOADing) is probably a less commonly used feature. One use is including additional functionality such as making the statically linked executable "trashcan friendly" by default, perhaps using delsafe, but without needing to install any additional software on the machine that is running the statically linked executable.

Security measures that randomize the address space of binaries might interfere with ELF Statifier and cause it not to work. But when you just want to move the execution of an application to another Linux machine, ELF Statifier might get you up and running without the hassle of a recompile.

Ben Martin has been working on filesystems for more than 10 years. He completed his Ph.D. and now offers consulting services focused on libferris, filesystems, and search solutions.

Share    Print    Comments   


on Quickly move an executable between systems with ELF Statifier

Note: Comments are owned by the poster. We are not responsible for their content.

Quickly move an executable between systems with ELF Statifier

Posted by: Anonymous [ip:] on October 23, 2008 10:21 AM
Can this be used to create a binary which will run in both Linux and Cygwin?


Re: Quickly move an executable between systems with ELF Statifier

Posted by: Anonymous [ip:] on October 23, 2008 11:15 AM
No, since cygwin does not use ELF executables but PE executables (as is common on Windows).


Quickly move an executable between systems with ELF Statifier

Posted by: Anonymous [ip:] on October 23, 2008 11:34 AM
Transfering executables between systems is a great way to propagate malware - just cause its not some other OS is no excuse to be lax

Its *source* code that you transfer between machines, besides I don't even have 2 machines with compatible processors anyhow!!!

Quite what is a "hassle" about recompiling is beyond me....


Not just disk space

Posted by: Anonymous [ip:] on October 23, 2008 02:29 PM
"Of course, to do this you sacrifice some disk space, because the statically linked executable includes a copy of the shared libraries that it needs"

It's not just disk space. You also waste RAM, because a shared library is loaded into memory only once, even if several programs use it. That is MUCH more important than the disk space.

In general, if a program has not been packaged for your distro, you need to rebuild it, as wrote. If the standard configure/make/make install doesn't work, then ELF Stratifier probably wouldn't have worked either. But the standard procedure nearly always gives you a clue about what you have to do to get it to build.


Quickly move an executable between systems with ELF Statifier

Posted by: Anonymous [ip:] on October 23, 2008 03:03 PM
Some comments:

1. Environment: Statifier does not set environment variables for the statified executable.
It just allows one to specify them during statifying process to influence linking (think LD_BIND_NOW, LD_LIBRARY_PATH, LD_PRELOAD, etc). Any of those environment variables set at runtime will be passed through to the executable without modification.

2) Randomization: the statified executable fails, but the commercial alternative Ermine ( uses a different approach that works with memory randomization.
Thus there's no need for root access

3) On the ls example:
This program uses libnss_* libraries. When statified as in the article those libraries will
not be packed. Consequently moving the executables to the target system can be a problem.
The correct way to pack such executable is to specify ALL /lib/libnss* libraries with -eLD_PRELOAD.
Ermine supports this with the switch --with-nss='internal'.


Quickly move an executable between systems with ELF Statifier

Posted by: Anonymous [ip:] on October 23, 2008 06:19 PM
This type of thing is useful on a case by case basis. Often times I have needed to run something on another machine on which I do not have admin privileges or has a different version of libc or other libraries. I essentially ran ldd on the executable and copied the libraries over to a local directory. This is not the long term 'right' way of setting up a process but strange circumstances exist with work or whatever, where you need to rig together a quick solution.

Check out ldd, it lists which libraries an executable will look for.


Quickly move an executable between systems with ELF Statifier

Posted by: Anonymous [ip:] on October 23, 2008 11:19 PM
This program came in pretty handy recently.

I use SystemImager to install linux images and on some machines it was going pretty slow. (3-4 hours) It was because the network switches were set at 100Mbps Full duplex Autoneg off with no way to change it.
SystememImagers PXE environment tried to use Autoneg. It failed and fell back to 10Mbps half duplex.

To force it to run at 100Mbps full duplex, I needed to run "ethtool" before the image loading began. A regular ethtool did not work because the required libraries were missing in the bare PXE environment.

This is where statifier came in handy. I created a static ethtool on another server, copied it to a location from where I could call it in SystemImagers scripts just before the image loading began.
And SystemImager was back to loading images in 10 mins.


This story has been archived. Comments can no longer be posted.

Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya