#609882 libc6: "No such file or directory" error when attempting to execute LSB executable without lsb-core #609882
- Package:
- command-not-found
- Source:
- command-not-found
- Submitter:
- Graham Inggs
- Date:
- 2017-11-22 06:21:06 UTC
- Severity:
- wishlist
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
reassign 609882 command-not-found thanks I fail to see the relation with libc6. Reassigning to the "command-not-found" package.
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
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
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?
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".
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
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.
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.)
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.
# 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
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.