[comp.lang.perl] #! troubles

worley@compass.com (Dale Worley) (01/08/90)

The *real* solution for this problem is to have the kernel search your
path when it sees a #!.  Otherwise, you have to be root to install a
new interpreter in the "standard" place, because the #!'s have the
interpreter's location hardcoded in.

Dale Worley		Compass, Inc.			worley@compass.com
--
The trouble with normal is it always gets worse.  --Bruce Cockburn

daveb@i88.isc.com (Dave Burton) (01/11/90)

In article <1970@uvaarpa.virginia.edu> worley@compass.com writes:
|The *real* solution for this problem is to have the kernel search your
|path when it sees a #!.  Otherwise, you have to be root to install a
|new interpreter in the "standard" place, because the #!'s have the
|interpreter's location hardcoded in.

Assuming the kernel gets your $PATH (which it doesn't, but pretend) -

What happens when the PATH is ".:/bin:/usr/bin", and the
script is suid root? How about:

	$ cd
	$ cat > sh.c
	main()
	{
		setuid(0);
		execl("/bin/sh", "sh", (char *)0);
	}
	^D
	$ cc -o sh sh.c
	$ cat script
	#!sh
	echo oops!
	$ ls -l script
	-rwsr-xr-x  1 root           16 Jul 26 16:19 script
	$ script
	# 

Searching $PATH is definitely NOT for the kernel.

-- Dave Burton
--
Dave Burton
uunet!ism780c!laidbak!daveb

worley@compass.com (Dale Worley) (01/13/90)

   X-Name: Dave Burton

   In article <1970@uvaarpa.virginia.edu> worley@compass.com writes:
   |The *real* solution for this problem is to have the kernel search your
   |path when it sees a #!.  Otherwise, you have to be root to install a
   |new interpreter in the "standard" place, because the #!'s have the
   |interpreter's location hardcoded in.

   Assuming the kernel gets your $PATH (which it doesn't, but pretend) -

Well, exec() seems to be able to pass it to the new program, and
exec() seems to be a kernel call...

   What happens when the PATH is ".:/bin:/usr/bin", and the
   script is suid root? How about:

Yes, of course, if you have a setuid script, you don't want to have
the kernel search the path for the interpreter.  But setuid things are
*always* a special case.  If you want to write setuid scripts, you
have to have a trusted interpreter, and root has to install it in a
safe place, and the script has to hard-code its location.  

But in the ordinary case, it would make life much easier if
interpreter paths didn't have to be hard-coded.

Dale Worley		Compass, Inc.			worley@compass.com
--
...and finally, a thought that I ripped off from someone a few months back:

Let us live!!!
Let us love!!!
Let us share the deepest secrets of our souls!!!

You first.

daveb@i88.isc.com (Dave Burton) (01/16/90)

[ Followups redirected to comp.unix.questions ]

In article <2047@uvaarpa.virginia.edu> worley@compass.com writes:
>> Assuming the kernel gets your $PATH (which it doesn't, but pretend) -
>
> Well, exec() seems to be able to pass it to the new program, and
> exec() seems to be a kernel call...

(Pedantic: In 4.[23]bsd exec() is not a syscall, nor even a standard
C library call. See execve(2), execl(3) in the BSD manuals. In SVR3.x,
exec() _is_ a kernel routine and is in sysent, but the libraries don't
reference it and I'll be hanged if I know who uses it.)

The kernel does not get _any_ environment variables. Sure, it passes an
environment pointer to the exec'd process, but this does not imply the
environment is scanned. That would be _very_ expensive.

>> What happens when the PATH is ".:/bin:/usr/bin", and the
>> script is suid root? How about:
>
> Yes, of course, if you have a setuid script, you don't want to have
> the kernel search the path for the interpreter.  But setuid things are
> *always* a special case.  If you want to write setuid scripts, you
> have to have a trusted interpreter, and root has to install it in a
> safe place, and the script has to hard-code its location.  
>
> But in the ordinary case, it would make life much easier if
> interpreter paths didn't have to be hard-coded.

If you are not on a system supporting #!, this whole topic is moot since
the interpreter will not be invoked, no matter where it lives. The shell
will simply complain of syntax errors. (I think SVR3.2 csh attempts #! by
itself, so these csh users may disagree here.)

Otherwise:

If you are root, this point is moot, as you can scribble anywhere you please.
Put the interpreter in /usr/local/bin and leave the scripts alone.

If you are not root, then put the interpreter where you want/can, and change
the #! line to point to this location. The only time this comes into play is
with scripts received from a third party, since (presumably) locally written
scripts know where their interpreter lives. Third party scripts are handled
anyway (stripping off mail headers, for instance), so the additional effort
to change "#!/usr/local/bin/x" to, say, "#!/u/myname/bin/x" is trivial. This
is little justification to change the kernel.

If you're adamant, petition your UNIX vendor. (Don't expect much.)

> Dale Worley		Compass, Inc.			worley@compass.com
--
Dave Burton
uunet!ism780c!laidbak!daveb

tjo@its.bt.co.uk (Tim Oldham) (01/17/90)

In article <1970@uvaarpa.virginia.edu> worley@compass.com writes:
>The *real* solution for this problem is to have the kernel search your
>path when it sees a #!.  Otherwise, you have to be root to install a
>new interpreter in the "standard" place, because the #!'s have the
>interpreter's location hardcoded in.

On our machines - made by BT and running V.3.2 - we didn't have #!.
Since I run bash as my login shell, I hacked the code to support #!.
I did it the lazy way and let bash start up fully, and then
execvp() the interpreter a la BSD. Just needs a few hooks in the lexical
analyser, a new yacc rule, and the actual code to execvp as necessary.
This of course is inefficient, as bash starts up fully only (all the
initialisation etc) to execvp whatever interpreter is necessary.
This actually means that the #! is recognised wherever it happens to be,
as long it's at the beginning of a line. Not much use, tho'.

The use of execvp means that you get path searching.

	Tim.
-- 
Tim Oldham, BT Applied Systems. tjo@its.bt.co.uk or ...!ukc!axion!its!tjo
Less is more, but not as much as more.