#!
Posted Nov 24, 2010 10:14 UTC (Wed) by
neilbrown (subscriber, #359)
In reply to:
#! by eru
Parent article:
Ghosts of Unix past, part 4: High-maintenance designs
Before #!,
execve("/path/of/script",argv,envp)
would fail. The shell would catch this failure, possible read the start of the script to see if it looked OK, and try
argv[-1] = "/path/of/script";
execve("/path/to/shell", argv-1, envp);
(though it wouldn't have used a -1 index it would have re-allocated, but you get the idea). The shell still does this so you can run a script without "#!" at the front.
So you could run scripts as executables, but only using a shell (e.g. system()), not using execve, and there was no opportunity for the kernel to impose setuid.
With the invention of '#!', this functionality was moved into the kernel.
The kernel would look at the first few bytes of the program and decide how to execute it, either by reading it into an address space, or running an interpreter to read the script. As it was done in the kernel, setuid could be effective and was - in most versions of Unix.
As has been noted in an earlier comment, Linux doesn't impose setuid on scripts. This is because setuid is effected by a call to setup_new_exec() which the individual format handlers call, and binfmt_script doesn't call it.
(
Log in to post comments)