[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#963508: /lib/ld-linux.so.2: LD_PRELOAD breaks with plain filename



On 2020-06-22 19:00, Ian Jackson wrote:
> Package: libc6
> Version: 2.28-10
> Severity: normal
> File: /lib/ld-linux.so.2
> 
> Hi.  I found this behaviour:
> 
> $ eatmydata man ls >/dev/null 
> ERROR: ld.so: object 'libeatmydata.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> ERROR: ld.so: object 'libeatmydata.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> ERROR: ld.so: object 'libeatmydata.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> ERROR: ld.so: object 'libeatmydata.so' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> $

You probably have apparmor installed and enabled on your system.
Binaries that are run with an apparmor profile get AT_SECURE enabled,
which disables many features that have an impact on security, including
preloading libraries.

> Experimenting shows that the problem is triggered by having LD_PRELOAD
> containing only the library name:
> 
> $ faketime yesterday printenv | grep PREL
> LD_PRELOAD=libgtk3-nocsd.so.0:/usr/$LIB/faketime/libfaketime.so.1
> $ faketime yesterday env LD_PRELOAD=libfaketime.so.1 man ls >/dev/null 
> ERROR: ld.so: object 'libfaketime.so.1' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> ERROR: ld.so: object 'libfaketime.so.1' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> ERROR: ld.so: object 'libfaketime.so.1' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> ERROR: ld.so: object 'libfaketime.so.1' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> ERROR: ld.so: object 'libfaketime.so.1' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> ERROR: ld.so: object 'libfaketime.so.1' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> ERROR: ld.so: object 'libfaketime.so.1' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> ERROR: ld.so: object 'libfaketime.so.1' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> $

faketime.so.1 is not in the standard path, ie on an amd64 system not
directly in /usr/lib/x86_64-linux-gnu:

$ dpkg -L libfaketime | grep libfaketime.so.1
/usr/lib/x86_64-linux-gnu/faketime/libfaketime.so.1

So you definitely need to use the full path, or add that path to
LD_LIBRARY_PATH or to /etc/ld.so.conf.

> The problem is not limited to man:
> 
> $ faketime yesterday env LD_PRELOAD=libfaketime.so.1 dash -c true
> ERROR: ld.so: object 'libfaketime.so.1' from LD_PRELOAD cannot be preloaded (cannot open shared object file): ignored.
> $

Same issue here, you can't just assume that /lib/ld-linux.so.2 will
search on the full filesystem. Here are the paths that are searched
according to the man page:

If a shared object dependency does not contain a slash, then it is
searched for in the following order:

- Using the directories specified in the DT_RPATH dynamic section
  attribute of the binary if present and DT_RUNPATH attribute does not
  exist. Use of DT_RPATH is deprecated.

- Using the environment variable LD_LIBRARY_PATH, unless the executable
  is being run in secure-execution mode (see below), in which case this
  variable is ignored.

- Using the directories specified in the DT_RUNPATH dynamic section
  attribute of the binary if present. Such directories are searched only
  to find those objects required by DT_NEEDED (direct dependencies)
  entries and do not apply to those objects' children, which must
  themselves have their own DT_RUNPATH entries. This is unlike DT_RPATH,
  which is applied to searches for all children in the dependency tree.

- From the cache file /etc/ld.so.cache, which contains a compiled list
  of candidate shared objects previously found in the augmented library
  path. If, however, the binary was linked with the -z nodeflib linker
  option, shared objects in the default paths are skipped. Shared
  objects installed in hardware capability directories (see below) are
  preferred to other shared objects.

- In the default path /lib, and then /usr/lib. (On some 64-bit
  architectures, the default paths for 64-bit shared objects are /lib64,
  and then /usr/lib64.) If the binary was linked with the -z nodeflib
  linker option, this step is skipped.

> This message on debian-user seems related:
>   https://lists.debian.org/debian-user/2017/03/msg00335.html

Yes, there seems to be an issue there, but I am personally not able to
reproduce it. Note however that I only tried it in a jessie chroot, not
in a complete jessie system.

> Colin Watson (CC'd) reports that sid works.

I have tested on sid and on experimental, I do not find a different
behaviour.

Regards,
Aurelien

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurelien@aurel32.net                 http://www.aurel32.net


Reply to: