2002-09-15 17:10:45

by Pozsar Balazs

[permalink] [raw]
Subject: [BUG?] binfmt_script: interpreted interpreter doesn't work


Hi all,

This may well not be bug, rather an intended feature, but please enlighten
me why the following doesn't work:

I have two scripts:
/home/pozsy/a:
#!/bin/sh
echo "Hello from a!"

/home/pozsy/b:
#!/home/pozsy/a
echo "hello from b!"


Both of them has +x permissions.
But I cannot execute the /home/pozsy/b script:

[pozsy:~]$ strace -f /home/pozsy/b
execve("/home/pozsy/b", ["/home/pozsy/b"], [/* 25 vars */]) = 0
strace: exec: Exec format error
[pozsy:~]$


Isn't this "indirection" allowed?

--
pozsy


2002-09-15 19:00:31

by Gilad Ben-Yossef

[permalink] [raw]
Subject: Re: [BUG?] binfmt_script: interpreted interpreter doesn't work

On Sun, 2002-09-15 at 20:15, Pozsar Balazs wrote:

> This may well not be bug, rather an intended feature, but please enlighten
> me why the following doesn't work:
>
> I have two scripts:
> /home/pozsy/a:
> #!/bin/sh
> echo "Hello from a!"
>
> /home/pozsy/b:
> #!/home/pozsy/a
> echo "hello from b!"
>
>
> Both of them has +x permissions.
> But I cannot execute the /home/pozsy/b script:
>
> [pozsy:~]$ strace -f /home/pozsy/b
> execve("/home/pozsy/b", ["/home/pozsy/b"], [/* 25 vars */]) = 0
> strace: exec: Exec format error
> [pozsy:~]$
>
>
> Isn't this "indirection" allowed?

hm... never chcked the code but I think /home/pozsy/a needs to be in
/etc/shells

What are you trying to do, anyway?

Cheers,
Gilad.

--
Gilad Ben-Yossef <[email protected]>
http://benyossef.com

"We don't need kernel hackers or geniuses, we need good developers who
will do what they're told". Famous last words, the collection.

2002-09-15 19:08:41

by Pozsar Balazs

[permalink] [raw]
Subject: Re: [BUG?] binfmt_script: interpreted interpreter doesn't work


On Sun, 15 Sep 2002, Hans-Peter Jansen wrote:

> > Consider these two scripts:
> >
> > /home/pozsy/a:
> > #!/usr/bin/perl
> > print <>;
> >
> > /home/pozsy/b:
> > #!/home/pozsy/a
> > "This is some text to printed out by the 'a' script"

> What's the problem?

I have a script written in perl, which interprets its input (or the files
in its arguments) [this is "a" in the above example]. I want to use this
script, as an interpreter to another "script" [the "b" in the above
example].

I well know bash, but this has nothing to do with shell coding.

Try my above example and you will understand what the problem is.
If you execute /home/pozsy/b, you _should_ get this as the output (2
lines) (the "a" program simply cats its input or argument files to its
output):
#!/home/pozsy/b
"This is some text to printed out by the 'a' script"

BUT this is what you get (1 line):
/home/pozsy/b: This is some text to printed out by the 'a' script: command
not found

This is because the kernel cannot execute the "/home/pozsy/b" script, and
then bash tries to interpret it itself. (but this in *not* what I want: I
want the "b" 'script' interpreted by the "a" script).
If you try this:
strace -f /home/pozsy/b
You will get this:
execve("/home/pozsy/b", ["/home/pozsy/b"], [/* 24 vars */]) = 0
strace: exec: Exec format error

The root of the problem is still that /home/pozsy/b cannot be execve'd.
That is a kernel problem.

--
pozsy


2002-09-15 19:09:24

by Pozsar Balazs

[permalink] [raw]
Subject: Re: [BUG?] binfmt_script: interpreted interpreter doesn't work

On 15 Sep 2002, Gilad Ben-Yossef wrote:

> On Sun, 2002-09-15 at 20:15, Pozsar Balazs wrote:
>
> > This may well not be bug, rather an intended feature, but please enlighten
> > me why the following doesn't work:
> >
> > I have two scripts:
> > /home/pozsy/a:
> > #!/bin/sh
> > echo "Hello from a!"
> >
> > /home/pozsy/b:
> > #!/home/pozsy/a
> > echo "hello from b!"
> >
> >
> > Both of them has +x permissions.
> > But I cannot execute the /home/pozsy/b script:
> >
> > [pozsy:~]$ strace -f /home/pozsy/b
> > execve("/home/pozsy/b", ["/home/pozsy/b"], [/* 25 vars */]) = 0
> > strace: exec: Exec format error
> > [pozsy:~]$
> >
> >
> > Isn't this "indirection" allowed?
>
> hm... never chcked the code but I think /home/pozsy/a needs to be in
> /etc/shells

No, that has nothing to do with this.

> What are you trying to do, anyway?

See my other post.

--
pozsy

2002-09-15 19:29:20

by Willy Tarreau

[permalink] [raw]
Subject: Re: [BUG?] binfmt_script: interpreted interpreter doesn't work

On Sun, Sep 15, 2002 at 09:13:30PM +0200, Pozsar Balazs wrote:

> This is because the kernel cannot execute the "/home/pozsy/b" script, and
> then bash tries to interpret it itself. (but this in *not* what I want: I
> want the "b" 'script' interpreted by the "a" script).
> If you try this:
> strace -f /home/pozsy/b
> You will get this:
> execve("/home/pozsy/b", ["/home/pozsy/b"], [/* 24 vars */]) = 0
> strace: exec: Exec format error
>
> The root of the problem is still that /home/pozsy/b cannot be execve'd.
> That is a kernel problem.

the problem is far simpler :
when you execute /home/pozsy/b, the kernel should have to launch /home/pozsy/a
with /home/pozsy/b in argv[0]. If it accepted to run it, it would run sh (or
perl or any other interpreter) with /home/pozsy/a in argv[0], thus loosing
track of /home/pozsy/b.

The simplest solution for you is to write a little C wrapper to start your
interpreted interpreter with the script in argument. Written with dietlibc or
anything like it, it would not be more than a few hundred bytes long.

Cheers,
Willy

2002-09-15 20:40:28

by Ingo Oeser

[permalink] [raw]
Subject: Re: [BUG?] binfmt_script: interpreted interpreter doesn't work

Hi Pozsar,

On Sun, Sep 15, 2002 at 07:15:38PM +0200, Pozsar Balazs wrote:
> This may well not be bug, rather an intended feature, but please enlighten
> me why the following doesn't work:
>
> I have two scripts:
> /home/pozsy/a:
> #!/bin/sh
> echo "Hello from a!"
>
> /home/pozsy/b:
> #!/home/pozsy/a
> echo "hello from b!"
>
> Both of them has +x permissions.
> But I cannot execute the /home/pozsy/b script:
>
> Isn't this "indirection" allowed?

Right, this isn't allowed to avoid eating kernel resources
without getting anything done.

Solution is to always compile an interpreter or to write
a wrapper in C, which is compiled and calls the perl interpreter
with your perl script. This wrapper would be ANSI-C with really
basic POSIX extensions and should thus be as portable as perl ;-)

So you hide the indirection from the kernel this way.

Of course you now define the wrapper as the interpreter for your
perl scripts.

Hope that helps.

Regards

Ingo Oeser
--
Science is what we can tell a computer. Art is everything else. --- D.E.Knuth

2002-09-15 20:56:14

by Pozsar Balazs

[permalink] [raw]
Subject: Re: [BUG?] binfmt_script: interpreted interpreter doesn't work

On Sun, 15 Sep 2002, Willy Tarreau wrote:

> On Sun, Sep 15, 2002 at 09:13:30PM +0200, Pozsar Balazs wrote:
>
> > This is because the kernel cannot execute the "/home/pozsy/b" script, and
> > then bash tries to interpret it itself. (but this in *not* what I want: I
> > want the "b" 'script' interpreted by the "a" script).
> > If you try this:
> > strace -f /home/pozsy/b
> > You will get this:
> > execve("/home/pozsy/b", ["/home/pozsy/b"], [/* 24 vars */]) = 0
> > strace: exec: Exec format error
> >
> > The root of the problem is still that /home/pozsy/b cannot be execve'd.
> > That is a kernel problem.
>
> the problem is far simpler :
> when you execute /home/pozsy/b, the kernel should have to launch /home/pozsy/a
> with /home/pozsy/b in argv[0]. If it accepted to run it, it would run sh (or
> perl or any other interpreter) with /home/pozsy/a in argv[0], thus loosing
> track of /home/pozsy/b.
>
> The simplest solution for you is to write a little C wrapper to start your
> interpreted interpreter with the script in argument. Written with dietlibc or
> anything like it, it would not be more than a few hundred bytes long.

I wrote a little wrapper, but that showed me that the kernel does _not_
replace argv[0], instead it pushes the original argv[0] into argv[1] or
argv[2].
So we would not loose track of the original name, as interpreters could be
called like this:
/interpreter1 script
/interpreter2 /interpreter1 script
/interpreter3 /interpreter2 /interpreter1 script
...and so on.

--
pozsy


2002-09-15 20:59:14

by Pozsar Balazs

[permalink] [raw]
Subject: Re: [BUG?] binfmt_script: interpreted interpreter doesn't work

On Sun, 15 Sep 2002, Ingo Oeser wrote:

> Hi Pozsar,
>
> On Sun, Sep 15, 2002 at 07:15:38PM +0200, Pozsar Balazs wrote:
> > This may well not be bug, rather an intended feature, but please enlighten
> > me why the following doesn't work:
> >
> > I have two scripts:
> > /home/pozsy/a:
> > #!/bin/sh
> > echo "Hello from a!"
> >
> > /home/pozsy/b:
> > #!/home/pozsy/a
> > echo "hello from b!"
> >
> > Both of them has +x permissions.
> > But I cannot execute the /home/pozsy/b script:
> >
> > Isn't this "indirection" allowed?
>
> Right, this isn't allowed to avoid eating kernel resources
> without getting anything done.
>
> Solution is to always compile an interpreter or to write
> a wrapper in C, which is compiled and calls the perl interpreter
> with your perl script. This wrapper would be ANSI-C with really
> basic POSIX extensions and should thus be as portable as perl ;-)
>
> So you hide the indirection from the kernel this way.
>
> Of course you now define the wrapper as the interpreter for your
> perl scripts.
>
> Hope that helps.

Ok, using a C wrapper I can workaround the problem. But that is ugly,
and I do not see the point why cannot be the indirection level, say, 5.

I have also had a look at fs/exec.c and fs/binfmt_script.c and I cannot
see where the 1-level comes from. Could anyone explain?

--
pozsy

2002-09-15 21:02:41

by Mark Veltzer

[permalink] [raw]
Subject: Re: [BUG?] binfmt_script: interpreted interpreter doesn't work

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Sunday 15 September 2002 23:06, Ingo Oeser wrote:
> Hi Pozsar,
>

> Right, this isn't allowed to avoid eating kernel resources
> without getting anything done.

You mean like writing a program to calculate PI to the 1,000,000th digit ?
The kernel is not supposed to dictate what is done with it. If the user wants
to link 10,000 such scripts in a chain then let him. I suspect that that
isn't the problem. The problem is that before the launch of the program the
time is not counted as time spent on that specific user and so this could be
used as loop hole to drain resources from other users. If this is the case
then this time should be accounted for (I'm not sure about this though and if
the time is accounted for then I don't see any reason to disable the chains
except avoiding cycles which needs some coding).

>
> Solution is to always compile an interpreter or to write
> a wrapper in C, which is compiled and calls the perl interpreter
> with your perl script. This wrapper would be ANSI-C with really
> basic POSIX extensions and should thus be as portable as perl ;-)

There is actually already a program that one can use. It's /usr/bin/env and
is part of the sh-utils package from GNU. I always use and instead of writing
something like:

#!/usr/bin/perl
.....

I write:

#!/usr/bin/env perl
.....

This way the users preferred perl is used and I'm reducing all my arbitrary
assumptions about locations of executables to one assumption about the
location of /usr/bin/env (one hardcoded fact is better than many cause it's
easier to fix if need be).

You can use env to solve your problem. In your scripts replace all shbang
lines. /usr/bin/env is, ofcourse, a binary executable.

Name: Mark Veltzer
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE9hPkuxlxDIcceXTgRAgB+AKCJ8JtVKrpNfnaTy7/kQASSEtxsdACgyPl/
czeMVYsD5Qp+da49hyoPpFc=
=Ux8a
-----END PGP SIGNATURE-----

2002-09-15 21:06:49

by jbradford

[permalink] [raw]
Subject: Re: [BUG?] binfmt_script: interpreted interpreter doesn't work

> > This may well not be bug, rather an intended feature, but please enlighten
> > me why the following doesn't work:
> >
> > I have two scripts:
> > /home/pozsy/a:
> > #!/bin/sh
> > echo "Hello from a!"
> >
> > /home/pozsy/b:
> > #!/home/pozsy/a
> > echo "hello from b!"
> >
> > Both of them has +x permissions.
> > But I cannot execute the /home/pozsy/b script:
> >
> > Isn't this "indirection" allowed?

The whole #!/foo/bar notation seems to be very mis-understood these days, it is not just notation chosen at random to be an indicator of the interpreter for the rest of the script - a good explaination can be found at faqs.org:

http://www.faqs.org/faqs/unix-faq/faq/part3/section-16.html