[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



Aurelien Jarno writes ("Re: Bug#963508: /lib/ld-linux.so.2: LD_PRELOAD breaks with plain filename"):
> 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.

Hi.  Thanks for your reply.  apparmor may well be involved, and indeed
you are right to point out that the faketime repro is a red herring,

But I think things are more complicated.

Should apparmor make a difference between absolute paths and leafnames
in LD_PRELOAD ?  Because I can reproduce that with eatmydata:
  $ eatmydata env -u LD_LIBRARY_PATH LD_PRELOAD='/usr/lib/x86_64-linux-gnu/libeatmydata.so' man ls >/dev/null
  $

strace in the run with the error message[1] shows it does successfully
open the intended .so file.  But then it goes on to try lots of other
places instead and eventually prints that error message.  It seems
that it opened the file but rejected it.

I notice that during startup it does this
  access("/etc/suid-debug", F_OK)         = -1 ENOENT (No such file or
but none of my man-db binaries are setuid (I have double-checked).

I also notice that something in the invocation stack (presumably
something in man-db) is changing the LD_PRELOAD value from
  LD_PRELOAD=libgtk3-nocsd.so.0 libeatmydata.so
to
  LD_PRELOAD=libgtk3-nocsd.so.0:libeatmydata.so
and I didn't even know spaces were allowed!  But this doesn't seem
relevant.

If this were apparmor I would expect to see an EACCES or EPERM or
something.  I searched the preconv strace for error reports and it
contains no E... other than (i) ENOENT (ii) this:
    seccomp(SECCOMP_SET_MODE_STRICT, 1, NULL) = -1 EINVAL (Invalid argument)

> 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:

You are right that all my discussion of faketime is a red herring,
because faketime's .so is not on the standard search path.

> If a shared object dependency does not contain a slash, then it is
> searched for in the following order:
...
> - 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.

Did you c&p that text from a pre-multiarch document ?  Evidently the
default search path does contain /usr/lib/x86_64-linux-gnu, which is
surely what is to be expected.  And that is where the eatmydata .so is
located and indeed it opens it!

And this works most of the time.  Just not in man.

(FTAOD I can't repro the eatmydata problem with dash.)

Ian.


[1] strace.  I did this:
  strace -ffot eatmydata env -u LD_LIBRARY_PATH man ls >/dev/null
This runs many processes but of these, the first to print the
error is `preconv':

  execve("/usr/bin/preconv", ["preconv", "-e", "UTF-8"], 0x55dc40160a50 /* 56 vars */) = 0
  ...
  access("/etc/suid-debug", F_OK)         = -1 ENOENT (No such file or
  directory)
  ...
  openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libeatmydata.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
  openat(AT_FDCWD, "/usr/lib/x86_64-linux-gnu/libeatmydata.so", O_RDONLY|O_CLOEXEC) = 5
  read(5, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\220\20\0\0\0\0\0\0"..., 832) = 832
  fstat(5, {st_mode=S_IFREG|0644, st_size=14176, ...}) = 0
  close(5)                                = 0
  openat(AT_FDCWD, "/lib/tls/haswell/avx512_1/x86_64/libeatmydata.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
  [... loads more like this ...]
  writev(2, [{iov_base="ERROR: ld.so: object '", iov_len=22}, {iov_base="libeatmydata.so", iov_len=15}, {iov_base="' from ", iov_len=7}, {iov_base="LD_PRELOAD", iov_len=10}, {iov_base=" cannot be preloaded (", iov_len=22}, {iov_base="cannot open shared object file", iov_len=30}, {iov_base="): ignored.\n", iov_len=12}], 7) = 118


> > 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.
> > $
> 
> > 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

-- 
Ian Jackson <ijackson@chiark.greenend.org.uk>   These opinions are my own.  

Pronouns: they/he.  If I emailed you from @fyvzl.net or @evade.org.uk,
that is a private address which bypasses my fierce spamfilter.


Reply to: