* [PATCH] Return ENOEXEC, not ENOENT, if a binary's or script's interpreter doesn't exist.
@ 2009-07-09 7:48 Geoffrey Thomas
2009-07-10 5:18 ` Amerigo Wang
2009-07-10 16:17 ` Pavel Machek
0 siblings, 2 replies; 6+ messages in thread
From: Geoffrey Thomas @ 2009-07-09 7:48 UTC (permalink / raw)
To: linux-kernel; +Cc: Geoffrey Thomas
If you try to execute a binary compiled for ld-linux.so.1 (libc5) on a machine
with only ld-linux.so.2 (libc6), your shell will claim "mybinary: No such file
or directory", even though the binary exists. The ENOENT actually applies to
the ELF intepreter, not to the file itself. The same happens if you have a
nonexistent interpreter in a shell script's shebang line.
Give a more helpful and more expected error, "cannot execute binary file", in
these cases.
Signed-off-by: Geoffrey Thomas <geofft@mit.edu>
Tested-by: Anders Kaseorg <andersk@mit.edu>
---
fs/binfmt_elf.c | 5 ++++-
fs/binfmt_elf_fdpic.c | 2 ++
fs/binfmt_em86.c | 8 ++++++--
fs/binfmt_misc.c | 5 ++++-
fs/binfmt_script.c | 8 ++++++--
5 files changed, 22 insertions(+), 6 deletions(-)
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index b7c1603..56954e4 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -685,8 +685,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
interpreter = open_exec(elf_interpreter);
retval = PTR_ERR(interpreter);
- if (IS_ERR(interpreter))
+ if (IS_ERR(interpreter)) {
+ if (retval == -ENOENT)
+ retval = -ENOEXEC;
goto out_free_interp;
+ }
/*
* If the binary is not readable then enforce
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 20fbece..604d117 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -232,6 +232,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
interpreter = open_exec(interpreter_name);
retval = PTR_ERR(interpreter);
if (IS_ERR(interpreter)) {
+ if (retval == -ENOENT)
+ retval = -ENOEXEC;
interpreter = NULL;
goto error;
}
diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
index 32fb00b..587e0b9 100644
--- a/fs/binfmt_em86.c
+++ b/fs/binfmt_em86.c
@@ -82,8 +82,12 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
* space, and we don't need to copy it.
*/
file = open_exec(interp);
- if (IS_ERR(file))
- return PTR_ERR(file);
+ if (IS_ERR(file)) {
+ if (PTR_ERR(file) == -ENOENT)
+ return -ENOEXEC;
+ else
+ return PTR_ERR(file);
+ }
bprm->file = file;
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index c4e8353..eecf0db 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -180,8 +180,11 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
interp_file = open_exec (iname);
retval = PTR_ERR (interp_file);
- if (IS_ERR (interp_file))
+ if (IS_ERR (interp_file)) {
+ if (retval == -ENOENT)
+ retval = -ENOEXEC;
goto _error;
+ }
bprm->file = interp_file;
if (fmt->flags & MISC_FMT_CREDENTIALS) {
diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
index 0834350..738446f 100644
--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -88,8 +88,12 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
* OK, now restart the process with the interpreter's dentry.
*/
file = open_exec(interp);
- if (IS_ERR(file))
- return PTR_ERR(file);
+ if (IS_ERR(file)) {
+ if (PTR_ERR(file) == -ENOENT)
+ return -ENOEXEC;
+ else
+ return PTR_ERR(file);
+ }
bprm->file = file;
retval = prepare_binprm(bprm);
--
1.5.6.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH] Return ENOEXEC, not ENOENT, if a binary's or script's interpreter doesn't exist.
2009-07-09 7:48 [PATCH] Return ENOEXEC, not ENOENT, if a binary's or script's interpreter doesn't exist Geoffrey Thomas
@ 2009-07-10 5:18 ` Amerigo Wang
2009-07-10 16:17 ` Pavel Machek
1 sibling, 0 replies; 6+ messages in thread
From: Amerigo Wang @ 2009-07-10 5:18 UTC (permalink / raw)
To: Geoffrey Thomas; +Cc: linux-kernel
On Thu, Jul 09, 2009 at 03:48:20AM -0400, Geoffrey Thomas wrote:
>If you try to execute a binary compiled for ld-linux.so.1 (libc5) on a machine
>with only ld-linux.so.2 (libc6), your shell will claim "mybinary: No such file
>or directory", even though the binary exists. The ENOENT actually applies to
>the ELF intepreter, not to the file itself. The same happens if you have a
>nonexistent interpreter in a shell script's shebang line.
>
>Give a more helpful and more expected error, "cannot execute binary file", in
>these cases.
>
>Signed-off-by: Geoffrey Thomas <geofft@mit.edu>
>Tested-by: Anders Kaseorg <andersk@mit.edu>
Well, this is arguable... ENOEXEC and ENOENT are hard to choose here,
but *personally* I agree with you according to your description.
And according to execve(2), this change breaks that documentation. If you
really want to fix this, please also update the man page.
/me is also wondering if this change will break any user-space programs?
Thank you!
>---
> fs/binfmt_elf.c | 5 ++++-
> fs/binfmt_elf_fdpic.c | 2 ++
> fs/binfmt_em86.c | 8 ++++++--
> fs/binfmt_misc.c | 5 ++++-
> fs/binfmt_script.c | 8 ++++++--
> 5 files changed, 22 insertions(+), 6 deletions(-)
>
>diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
>index b7c1603..56954e4 100644
>--- a/fs/binfmt_elf.c
>+++ b/fs/binfmt_elf.c
>@@ -685,8 +685,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
>
> interpreter = open_exec(elf_interpreter);
> retval = PTR_ERR(interpreter);
>- if (IS_ERR(interpreter))
>+ if (IS_ERR(interpreter)) {
>+ if (retval == -ENOENT)
>+ retval = -ENOEXEC;
> goto out_free_interp;
>+ }
>
> /*
> * If the binary is not readable then enforce
>diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
>index 20fbece..604d117 100644
>--- a/fs/binfmt_elf_fdpic.c
>+++ b/fs/binfmt_elf_fdpic.c
>@@ -232,6 +232,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
> interpreter = open_exec(interpreter_name);
> retval = PTR_ERR(interpreter);
> if (IS_ERR(interpreter)) {
>+ if (retval == -ENOENT)
>+ retval = -ENOEXEC;
> interpreter = NULL;
> goto error;
> }
>diff --git a/fs/binfmt_em86.c b/fs/binfmt_em86.c
>index 32fb00b..587e0b9 100644
>--- a/fs/binfmt_em86.c
>+++ b/fs/binfmt_em86.c
>@@ -82,8 +82,12 @@ static int load_em86(struct linux_binprm *bprm,struct pt_regs *regs)
> * space, and we don't need to copy it.
> */
> file = open_exec(interp);
>- if (IS_ERR(file))
>- return PTR_ERR(file);
>+ if (IS_ERR(file)) {
>+ if (PTR_ERR(file) == -ENOENT)
>+ return -ENOEXEC;
>+ else
>+ return PTR_ERR(file);
>+ }
>
> bprm->file = file;
>
>diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
>index c4e8353..eecf0db 100644
>--- a/fs/binfmt_misc.c
>+++ b/fs/binfmt_misc.c
>@@ -180,8 +180,11 @@ static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
>
> interp_file = open_exec (iname);
> retval = PTR_ERR (interp_file);
>- if (IS_ERR (interp_file))
>+ if (IS_ERR (interp_file)) {
>+ if (retval == -ENOENT)
>+ retval = -ENOEXEC;
> goto _error;
>+ }
>
> bprm->file = interp_file;
> if (fmt->flags & MISC_FMT_CREDENTIALS) {
>diff --git a/fs/binfmt_script.c b/fs/binfmt_script.c
>index 0834350..738446f 100644
>--- a/fs/binfmt_script.c
>+++ b/fs/binfmt_script.c
>@@ -88,8 +88,12 @@ static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
> * OK, now restart the process with the interpreter's dentry.
> */
> file = open_exec(interp);
>- if (IS_ERR(file))
>- return PTR_ERR(file);
>+ if (IS_ERR(file)) {
>+ if (PTR_ERR(file) == -ENOENT)
>+ return -ENOEXEC;
>+ else
>+ return PTR_ERR(file);
>+ }
>
> bprm->file = file;
> retval = prepare_binprm(bprm);
>--
>1.5.6.5
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH] Return ENOEXEC, not ENOENT, if a binary's or script's interpreter doesn't exist.
2009-07-09 7:48 [PATCH] Return ENOEXEC, not ENOENT, if a binary's or script's interpreter doesn't exist Geoffrey Thomas
2009-07-10 5:18 ` Amerigo Wang
@ 2009-07-10 16:17 ` Pavel Machek
1 sibling, 0 replies; 6+ messages in thread
From: Pavel Machek @ 2009-07-10 16:17 UTC (permalink / raw)
To: Geoffrey Thomas; +Cc: linux-kernel
On Thu 2009-07-09 03:48:20, Geoffrey Thomas wrote:
> If you try to execute a binary compiled for ld-linux.so.1 (libc5) on a machine
> with only ld-linux.so.2 (libc6), your shell will claim "mybinary: No such file
> or directory", even though the binary exists. The ENOENT actually applies to
> the ELF intepreter, not to the file itself. The same happens if you have a
> nonexistent interpreter in a shell script's shebang line.
>
> Give a more helpful and more expected error, "cannot execute binary file", in
> these cases.
NAK. Current behaviour is useful -- and it is really file thats
missing.
Please improve manpage instead.
(chmod 000 /lib also produces 'interesting' error messages. Better
document those, too). Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Return ENOEXEC, not ENOENT, if a binary's or script's interpreter doesn't exist.
@ 2009-07-30 17:08 Jonathan Reed
2009-07-30 20:12 ` Alan Cox
2009-07-30 20:17 ` Pavel Machek
0 siblings, 2 replies; 6+ messages in thread
From: Jonathan Reed @ 2009-07-30 17:08 UTC (permalink / raw)
To: Pavel Machek, Geoffrey Thomas; +Cc: linux-kernel
> NAK. Current behaviour is useful -- and it is really file thats
> missing.
The current behavior is only useful to people who have an understanding of
how interpreters and binaries work on Linux. The average desktop user
does not have that understanding. The average user gets an error message
such as:
/usr/bin/foo: No such file or directory.
They then go and look at /usr/bin/foo, find that it exists, and are
extremely confused.
More advanced users might at that point try and run "ldd" on the binary
(which will also fail, thanks to a missing interpreter). The average user
will never think to run "strings" on the binary and look for
/lib/ld-linux.so.1.
> Please improve manpage instead.
What manpage do you suggest needs improvement? execve(2)? That again
requires an average user to realize that they need to go look at the
execve(2) manpage. The average user is not going to realize that.
-Jon
---
Jonathan Reed
jdreed@mit.edu
Faculty and Student Experience
Information Services & Technology
Massachusetts Institute of Technology
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Return ENOEXEC, not ENOENT, if a binary's or script's interpreter doesn't exist.
2009-07-30 17:08 Jonathan Reed
@ 2009-07-30 20:12 ` Alan Cox
2009-07-30 20:17 ` Pavel Machek
1 sibling, 0 replies; 6+ messages in thread
From: Alan Cox @ 2009-07-30 20:12 UTC (permalink / raw)
To: Jonathan Reed; +Cc: Pavel Machek, Geoffrey Thomas, linux-kernel
> They then go and look at /usr/bin/foo, find that it exists, and are
> extremely confused.
-ENOEXEC is just as confusing. It is executable, it will match
(cmp/md5sum etc) with one on another box etc.
> More advanced users might at that point try and run "ldd" on the binary
> (which will also fail, thanks to a missing interpreter).
So fix ldd ?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] Return ENOEXEC, not ENOENT, if a binary's or script's interpreter doesn't exist.
2009-07-30 17:08 Jonathan Reed
2009-07-30 20:12 ` Alan Cox
@ 2009-07-30 20:17 ` Pavel Machek
1 sibling, 0 replies; 6+ messages in thread
From: Pavel Machek @ 2009-07-30 20:17 UTC (permalink / raw)
To: Jonathan Reed; +Cc: Geoffrey Thomas, linux-kernel
On Thu 2009-07-30 13:08:58, Jonathan Reed wrote:
>> NAK. Current behaviour is useful -- and it is really file thats
>> missing.
>
> The current behavior is only useful to people who have an understanding
> of how interpreters and binaries work on Linux. The average desktop
> user
Proposed behaviour is useless to everyone.
> does not have that understanding. The average user gets an error message
> such as:
>
> /usr/bin/foo: No such file or directory.
>
> They then go and look at /usr/bin/foo, find that it exists, and are
> extremely confused.
ENOEXEC is confusing, too. It will have x bit.
>> Please improve manpage instead.
>
> What manpage do you suggest needs improvement? execve(2)? That
>again
execve, I'd say.
> requires an average user to realize that they need to go look at the
> execve(2) manpage. The average user is not going to realize that.
Improve shells to provide more helpful error message?
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-07-30 20:17 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-09 7:48 [PATCH] Return ENOEXEC, not ENOENT, if a binary's or script's interpreter doesn't exist Geoffrey Thomas
2009-07-10 5:18 ` Amerigo Wang
2009-07-10 16:17 ` Pavel Machek
-- strict thread matches above, loose matches on Subject: below --
2009-07-30 17:08 Jonathan Reed
2009-07-30 20:12 ` Alan Cox
2009-07-30 20:17 ` Pavel Machek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox