Docker - /Bin/Sh: <File> Not Found - Bad Elf Interpreter - How to Add 32Bit Lib Support to a Docker Image

Docker - /bin/sh: file not found - bad ELF interpreter - how to add 32bit lib support to a docker image

UPDATE:

So the question becomes now:

  • What would be the best way to achive the same result without repos or internet connection?

You could use various non-official 32-bit images available on DockerHub, search for debian32, ubuntu32, fedora32, etc.

If you can't trust them, you can build such an image by yourself, and you can find instruction on DockerHub too, e.g.:

  • on f69m/ubuntu32 home page, there is a link to GitHub repo used to generate images;
  • on hugodby/fedora32 home page, there is an example of commands used to build the image;
  • and so on.

Alternatively, you can prepare your own image based on some official image and add 32-bit packages to it.

Say, you can use a Dockerfile like this:

FROM debian:wheezy
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y ia32-libs

...and use produced image as a base (with FROM directive) for images you're building without internet access.

You can even create an automated build on DockerHub that will rebuild your image automatically when your Dockerfile (posted, say, on GitHub) or mainline image (debian in the example above) changes.


No matter how did you obtain an image with 32-bit support (used existing non-official image or built your own), you can then store it to a tar archive using docker save command and then import using docker load command.

CentOS 64 bit bad ELF interpreter

You're on a 64-bit system, and don't have 32-bit library support installed.

To install (baseline) support for 32-bit executables

(if you don't use sudo in your setup read note below)

Most desktop Linux systems in the Fedora/Red Hat family:

 pkcon install glibc.i686

Possibly some desktop Debian/Ubuntu systems?:

pkcon install ia32-libs

Fedora or newer Red Hat, CentOS:

 sudo dnf install glibc.i686

Older RHEL, CentOS:

   sudo yum install glibc.i686

Even older RHEL, CentOS:

  sudo yum install glibc.i386

Debian or Ubuntu:

   sudo apt-get install ia32-libs

should grab you the (first, main) library you need.

Once you have that, you'll probably need support libs

Anyone needing to install glibc.i686 or glibc.i386 will probably run into other library dependencies, as well. To identify a package providing an arbitrary library, you can use

 ldd /usr/bin/YOURAPPHERE

if you're not sure it's in /usr/bin you can also fall back on

 ldd $(which YOURAPPNAME)

The output will look like this:

    linux-gate.so.1 =>  (0xf7760000)
libpthread.so.0 => /lib/libpthread.so.0 (0xf773e000)
libSM.so.6 => not found

Check for missing libraries (e.g. libSM.so.6 in the above output), and for each one you need to find the package that provides it.

Commands to find the package per distribution family

Fedora/Red Hat Enterprise/CentOS:

 dnf provides /usr/lib/libSM.so.6

or, on older RHEL/CentOS:

 yum provides /usr/lib/libSM.so.6

or, on Debian/Ubuntu:

first, install and download the database for apt-file

 sudo apt-get install apt-file && apt-file update

then search with

 apt-file find libSM.so.6

Note the prefix path /usr/lib in the (usual) case; rarely, some libraries still live under /lib for historical reasons … On typical 64-bit systems, 32-bit libraries live in /usr/lib and 64-bit libraries live in /usr/lib64.

(Debian/Ubuntu organise multi-architecture libraries differently.)

Installing packages for missing libraries

The above should give you a package name, e.g.:

libSM-1.2.0-2.fc15.i686 : X.Org X11 SM runtime library
Repo : fedora
Matched from:
Filename : /usr/lib/libSM.so.6

In this example the name of the package is libSM and the name of the 32bit version of the package is libSM.i686.

You can then install the package to grab the requisite library using pkcon in a GUI, or sudo dnf/yum/apt-get as appropriate…. E.g pkcon install libSM.i686. If necessary you can specify the version fully. E.g sudo dnf install ibSM-1.2.0-2.fc15.i686.

Some libraries will have an “epoch” designator before their name; this can be omitted (the curious can read the notes below).

Notes

Warning

Incidentially, the issue you are facing either implies that your RPM (resp. DPkg/DSelect) database is corrupted, or that the application you're trying to run wasn't installed through the package manager. If you're new to Linux, you probably want to avoid using software from sources other than your package manager, whenever possible...

If you don't use "sudo" in your set-up

Type

su -c

every time you see sudo, eg,

su -c dnf install glibc.i686

About the epoch designator in library names

The “epoch” designator before the name is an artifact of the way that the underlying RPM libraries handle version numbers; e.g.

2:libpng-1.2.46-1.fc16.i686 : A library of functions for manipulating PNG image format files
Repo : fedora
Matched from:
Filename : /usr/lib/libpng.so.3

Here, the 2: can be omitted; just pkcon install libpng.i686 or sudo dnf install libpng-1.2.46-1.fc16.i686. (It vaguely implies something like: at some point, the version number of the libpng package rolled backwards, and the “epoch” had to be incremented to make sure the newer version would be considered “newer” during updates. Or something similar happened. Twice.)


Updated to clarify and cover the various package manager options more fully (March, 2016)

Docker cookbook not finding Docker file

I believe you have a problem with the dockerfile instead of Chef.
You should keep in mind that you are providing a relative path to the source of the files you want to copy.

In order to fix this, try using absolute paths for source and target paths, something like:

FROM centos

COPY /root/dockerimages/CentOS/wafflehouse.repo /etc/yum.repos.d/wafflehouse.repo
COPY /root/dockerimages/CentOS/wafflehouse-artifacts.repo /etc/yum.repos.d/wafflehouse-artifacts.repo
COPY /root/dockerimages/CentOS/wafflehouse-snapshot-artifacts.repo /etc/yum.repos.d/wafflehouse-snapshot-artifacts.repo

RUN yum install -y net-tools

CMD ["bash"]

Docker Alpine executable binary not found even if in PATH

On Alpine Linux, the not found error is a typical symptom of dynamic link failure. It is indeed a rather confusing error by musl's ldd linker.

Most of the world Linux software is linked against glibc, the GNU libc library (libc provides the standard C library and POSIX API). Most Linux distributions are based on glibc. OTOH, Alpine Linux is based on the musl libc library, which is a minimal implementation and strictly POSIX compliant. Executables built on glibc distributions depend on /lib/x86_64-linux-gnu/libc.so.6, for example, which is not available on Alpine (unless, they are statically linked).

Except for this dependency, it's important to note that while musl attempts to maintain glibc compatibility to some extent, it is far from being fully compatible, and complex software that's built against glibc won't work with musl-libc, so simply symlinking /lib/ld-musl-x86_64.so.1 to the glibc path isn't likely going to work.

Generally, there are several ways for running glibc binaries on Alpine:

  1. Install one the glibc compatibility packages, libc6-compat or gcompat:
# apk add gcompat
apk add libc6-compat

Both packages provide a light weight glibc compatibility layer which may be suitable for running simple glibc applications.
libc6-compat implements glibc compatibility APIs and provides symlinks to glibc shared libraries such as libm.so, libpthread.so and libcrypt.so. The gcompat package is based on Adelie Linux gcompat project and does the same but provides a single library libgcompat.so. Both libraries install loader stubs. Depdending on the application, one of them may work while the other won't, so it's good to try both.


  1. Install proper glibc on Alpine, for providing all glibc methods and functionalities. There are glibc builds available for Alpine, which should be installed in the following procedure (example):
# Source: https://github.com/anapsix/docker-alpine-java

ENV GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc
ENV GLIBC_VERSION=2.30-r0

RUN set -ex && \
apk --update add libstdc++ curl ca-certificates && \
for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \
do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \
apk add --allow-untrusted /tmp/*.apk && \
rm -v /tmp/*.apk && \
/usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib

  1. Use statically linked executables. Static executables don't carry dynamic dependencies and could run on any Linux.

  2. Alternatively, the software may be built from source on Alpine.

For LibreDWG, let's first verify the issue:

/usr/local/bin # ./dwg2dxf
/bin/sh: ./dwg2dxf: not found
/usr/local/bin
/usr/local/bin # ldd ./dwg2dxf
/lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
libredwg.so.0 => /usr/local/lib/libredwg.so.0 (0x7fd3744db000)
libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
Error relocating /usr/local/lib/libredwg.so.0: __strcat_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __snprintf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __memcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __stpcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __strcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __printf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __fprintf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __strncat_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __sprintf_chk: symbol not found
Error relocating ./dwg2dxf: __snprintf_chk: symbol not found
Error relocating ./dwg2dxf: __printf_chk: symbol not found
Error relocating ./dwg2dxf: __fprintf_chk: symbol not found

You can see that dwg2dxf depends on several glibc symbols.
Now, let's follow option 2 for installing glibc:

/usr/src/app # cd /usr/local/bin
/usr/local/bin # ls
dwg2SVG dwg2dxf dwgadd dwgbmp dwgfilter dwggrep dwglayers dwgread dwgrewrite dwgwrite dxf2dwg dxfwrite
/usr/local/bin # ./dwg2dxf
/bin/sh: ./dwg2dxf: not found
/usr/local/bin # export GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc && \
> export GLIBC_VERSION=2.30-r0 && \
> apk --update add libstdc++ curl ca-certificates && \
> for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \
> do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \
> apk add --allow-untrusted /tmp/*.apk && \
> rm -v /tmp/*.apk && \
> /usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
(1/1) Installing curl (7.74.0-r1)
Executing busybox-1.32.1-r3.trigger
OK: 629 MiB in 126 packages
(1/2) Installing glibc (2.30-r0)
(2/2) Installing glibc-bin (2.30-r0)
Executing glibc-bin-2.30-r0.trigger
/usr/glibc-compat/sbin/ldconfig: /usr/local/lib/libredwg.so.0 is not a symbolic link
/usr/glibc-compat/sbin/ldconfig: /usr/glibc-compat/lib/ld-linux-x86-64.so.2 is not a symbolic link
OK: 640 MiB in 128 packages
removed '/tmp/glibc-2.30-r0.apk'
removed '/tmp/glibc-bin-2.30-r0.apk'
/usr/glibc-compat/sbin/ldconfig: /usr/glibc-compat/lib/ld-linux-x86-64.so.2 is not a symbolic link

/usr/glibc-compat/sbin/ldconfig: /usr/local/lib/libredwg.so.0 is not a symbolic link

Voila:

/usr/local/bin # ./dwg2dxf

Usage: dwg2dxf [-v[N]] [--as rNNNN] [-m|--minimal] [-b|--binary] DWGFILES...

Bash: No such file or directory?

I bet you miss dynamic linker. Just do a

readelf --all ./wkhtmltopdf | grep interpreter

You should get an output like this:

[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

There are high chances that you system lacks the interpreter (/lib64/ld-linux-x86-64.so.2 in the example). In this case bash would yell No such file or directory, just like when the binary itself is missing.

You can try to use a different linker. Sometime you can succeed. Just do a:

/path/to/the/linker /path/to/your/executable

This command:

find /lib* -name ld-linux\*

will help you find the linkers on your system. Or you can do the readelf command on some command that does run. It will show you correct, working linker.

OR, since you are running Debian system, just do a

sudo apt-get install wkhtmltopdf

to install native version of the tool :)

Linux executable fails with File not found even though the file is there and in PATH

This:

$ file /usr/bin/wine
/usr/bin/wine: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32,
BuildID[sha1]=eaf6de433d8196e746c95d352e0258fe2b65ae24, stripped

Combined with this:

$ ldd /usr/bin/wine
/usr/bin/ldd: line 117: /usr/bin/wine: No such file or directory

Strongly suggests that the system does not have the /lib/ld-linux.so.2 ELF interpreter. That is, this 64-bit system does not have any 32-bit compatibility libraries installed. Thus, @user1334609's answer is essentially correct.



Related Topics



Leave a reply



Submit