User: Password:
Subscribe / Log in / New account



Posted Nov 24, 2010 8:58 UTC (Wed) by eru (subscriber, #2753)
Parent article: Ghosts of Unix past, part 4: High-maintenance designs

This did not apply at the time that setuid was first invented, but once Unix gained the #!/bin/interpreter (or "shebang") method of running scripts it became possible for scripts to run setuid.

As I remember it, running scripts as if they were executables predates #!. The new notation merely allowed the script to specify the interpreter. In older Unix versions, the system simply tried to feed into /bin/sh any file with x permission that it did not recognize as a binary executable.

(Log in to post comments)


Posted Nov 24, 2010 10:14 UTC (Wed) by neilbrown (subscriber, #359) [Link]

Before #!,
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.

Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds