#609882 libc6: "No such file or directory" error when attempting to execute LSB executable without lsb-core

#609882#5
Date:
2011-01-13 13:34:34 UTC
From:
To:
On an amd64 architecture system without lsb-core installed, download
lmutil_x64_lsb.tar.gz from
http://www.globes.com/support/fnp_utilities_download.htm
Extract the file from the archive, mark it executable and then attempt
to execute it:

$ ./lmutil
bash: ./lmutil: No such file or directory

The error message should be more informative, for example:

This program requires 'lsb-core' which is currently not installed.  You
can install it by typing:
sudo apt-get install lsb-core

#609882#10
Date:
2011-01-13 22:43:30 UTC
From:
To:
reassign 609882 command-not-found
thanks

I fail to see the relation with libc6. Reassigning to the
"command-not-found" package.

#609882#21
Date:
2011-01-14 10:27:12 UTC
From:
To:
reassign 609882 bash
thanks

It looks like the commmand-not-found handler won't work here:
$ function command_not_found_handle { echo handled; }
$ export PATH=.:$PATH
$ lmutilfoo
handled
$ lmutil
bash: ./lmutil: No such file or directory

The program is there, on the path, but the interpretor required doesn't exist.

Yes, ld-linux doesn't seem to be involved:
$ strace -e execve -f sh -c ./lmutil
execve("/bin/sh", ["sh", "-c", "./lmutil"], [/* 55 vars */]) = 0
Process 14084 attached
[pid 14084] execve("./lmutil", ["./lmutil"], [/* 55 vars */]) = -1 ENOENT (No such file or directory)
sh: ./lmutil: not found
Process 14084 detached
--- SIGCHLD (Child exited) @ 0 (0) ---

It's rare for ELFs to require missing interpretors, so this is rather a special
case...
shell_execve (execute_cmd.c) does check for missing interpretors for
scripts (with shebangs) but not for ELFs

$ cat > testscript
#!/bin/foobarbaz
$ chmod +x testscript
$ testscript
bash: ./testscript: /bin/foobarbaz: bad interpreter: No such file or directory

Now, *that* gives a more useful error, maybe something to aim for.

SR

#609882#26
Date:
2012-01-27 14:11:20 UTC
From:
To:
Hi,

I did some investigating and came up with the following:

If you purge all packages which lsb-core depends on and lsb-core
itself,
lmutil remains functional, which is odd in the first place.
But if you look at the postinstall script of lsb-core the two symlinks
it creates make all the difference.  Unfortunately these symlinks to
_not_
get removed by the postrm script.

lsb-core.postinst:
amd64)
  [...]
  ln -sf /lib/ld-linux-x86-64.so.2 /lib64/ld-lsb-x86-64.so.2
  ln -sf /lib/ld-linux-x86-64.so.2 /lib64/ld-lsb-x86-64.so.3

Hope this helps.
Cheers Jan

#609882#31
Date:
2013-01-03 18:26:46 UTC
From:
To:
Timo Weingärtner <timo@tiwe.de> writes:

I think that's asking quite a lot of bash.  Wouldn't it have to open the
binary and parse the ELF headers, extracting the INTERP header, in order
to verify that?  Does it really make sense to encode understanding of ELF
binary layout formats in bash?

#609882#38
Date:
2013-01-03 18:37:44 UTC
From:
To:
Russ Allbery wrote:
[...]

I suppose it could check if the file exists itself, or it could always
use a message like "File or interpreter does not exist".

#609882#43
Date:
2013-01-03 18:42:42 UTC
From:
To:
Hallo Russ Allbery,

2013-01-03 um 19:26:46 schriebst Du:

As seen in strace bash already checks for existance of the script and the
#!interpreter. So when execve threw a ENOENT ("The file filename or a script
or ELF interpreter does not exist, or a shared library needed for file or
interpreter cannot be found.") it could at least say something like
"interpreter or libs not found, try ldd for debugging".


Grüße
Timo

#609882#48
Date:
2013-01-03 18:43:22 UTC
From:
To:
No, it doesn't.  Especially when binfmt_misc means you can get this error
from an arbitrary number of file formats with arbitrary levels of
interpreter nesting.

#609882#53
Date:
2013-01-03 18:44:11 UTC
From:
To:
Jonathan Nieder <jrnieder@gmail.com> writes:

I suppose, but I guess if I were the bash maintainer I would be unenthused
by this slippery slope.  Right now (presumably; I haven't looked at the
code), it's calling the appropriate syscall via libc, getting back ENOENT,
and printing out strerror(errno).

Messing about with checking things afterwards is sort of second-guessing
the kernel (what if the file was deleted between the point that it tried
to run it and the point at which it tried to check for its existence?).
If we want to distinguish between missing file and missing interpreter,
wouldn't it be better to introduce a new errno value that correctly
represents that difference?  After all, the kernel knows which problem it
had.  It just collapses them into a single errno value.

Of course, introducing a new errno value is hard and requires upstream
coordination between the kernel and glibc, not to mention some possible
impact on compatibility if any code out there is relying on getting ENOENT
when the interpreter isn't found.  Which, I suppose, is the argument for
doing this in bash.  (Although I'm inclined to agree with the original
reassignment of the bug: this sort of magic seems like what
command-not-found is for.)

#609882#58
Date:
2013-01-03 18:46:54 UTC
From:
To:
Timo Weingärtner <timo@tiwe.de> writes:

Hm, yes, I suppose that's true.  There's a race condition when the binary
is deleted between the ENOENT failure and the subsequent check, but
apparently bash is already living with that for the shell script check.
Okay, good point.

#609882#63
Date:
2013-01-03 19:21:39 UTC
From:
To:
# complex
severity 609882 wishlist
reassign 609882 command-not-found 0.2.38-1
quit

Russ Allbery wrote:
[...]

Yes, agreed.

At least I think that's the right place to experiment.  In the long
run, there's precedent for including this kind of thing in bash, as
Stefano mentioned:

| shell_execve (execute_cmd.c) does check for missing interpretors for
| scripts (with shebangs) but not for ELFs
|
| $ cat > testscript
| #!/bin/foobarbaz
| $ chmod +x testscript
| $ testscript
| bash: ./testscript: /bin/foobarbaz: bad interpreter: No such file or directory

Thanks for your thoughtfulness.
Jonathan

#609882#74
Date:
2013-01-03 20:17:20 UTC
From:
To:
This was discussed on Dec 26 on #-devel, a Fedora patch
(http://pkgs.fedoraproject.org/cgit/bash.git/tree/bash-2.05a-interpreter.patch)
was mentioned. Yes, it parses ELF headers.