[net.unix] inconsistency on read/execute permissions for shell procedures

gill@wanginst.UUCP (Timothy Gill) (07/02/85)

All of the UNIX documentation I read states that programs and other
executable files (shell procedures) are equivalent.  Yet I find that a
file with the permissions

	-rwx--x--- 

will execute for members of my group if it is a program but will not
execute if it is a shell procedure.  For a shell procedure to run for
those users, there must also be read permission on the file:

	-rwxr-x---

This is the case when my interactive shell is either "sh" or "csh".

This is clearly inconsistent.  Some people have tried to explain it to
me by saying that a shell procedure must be "read" by the shell to be
executed and that this is the reason the read permission must be there;
if this is so, why cannot the same reasoning me made for program
files?  They have to be "read" just as much as shell procedures.

The problem is that I wish some shell procedures to be executable by
other users without being readable by them, and the structure and
consistency of the UNIX file permission system leads me to believe that
this is possible.  However, I cannot make it happen.  Can someone inform
me how to make a shell procedure executable without it also being 
readable by others?

Nothing I have read states that the read permission must be set.  For 
example, Section 2.0 of Bourne's "An Introduction to the UNIX Shell"
states:

     UNIX files have three INDEPENDENT [my emphasis] attributes,
     "read", "write" and "execute". The UNIX command "chmod" (1)
     may be used to make a file executable.  For example, "chmod +x
     wg" will ensure that the file wg has execute status.
     Following this, the command "wg fred" is equivalent to "sh wg
     fred".  This allows shell procedures and programs to be used
     interchangeably.
     
So, can someone explain this UNIX inconsistency?

Responses mailed to me will be summarized for this group.

[We run Ultrix 1.0 (BSD 4.2)].

steve@tove.UUCP (Steve D. Miller) (07/06/85)

In article <761@wanginst.UUCP> gill@wanginst.UUCP (Timothy Gill) writes:
>All of the UNIX documentation I read states that programs and other
>executable files (shell procedures) are equivalent.  Yet I find that a
>file with the permissions
>
>	-rwx--x--- 
>
>will execute for members of my group if it is a program but will not
>execute if it is a shell procedure.  For a shell procedure to run for
>those users, there must also be read permission on the file:
>
>	-rwxr-x---
>
>This is the case when my interactive shell is either "sh" or "csh".
>
>This is clearly inconsistent.  Some people have tried to explain it to
>me by saying that a shell procedure must be "read" by the shell to be
>executed and that this is the reason the read permission must be there;
>if this is so, why cannot the same reasoning me made for program
>files?  They have to be "read" just as much as shell procedures.

   The problem is that when you run a shell script, the code that
actually starts things running looks at the first few bytes of the
file and decides whether or not it is a shell script.  If it is, then
the shell (sh, csh, or whatever) is executed so that the file is
its input.  For example, say you have a script named xyzzy that looks
like:

	#! /bin/csh <optional args>
	echo "Help Me Spock"
		.
		.
		.

   When the process is started, it is invoked as if you had typed
"/bin/csh xyzzy xyzzy <args>" (you can see this if you do a "ps"; I'm
not sure of the exact format, but that's the general idea).  Therefore,
the shell actually does an open() on xyzzy in an attempt to read
the commands there.  As one might expect, the open fails with 
"permission denied".

   I admit that it's inconvenient; maybe someone else has a better
workaround than the one I use (I rewrite it in C).
-- 
Spoken: Steve Miller 	ARPA:	steve@maryland	Phone: +1-301-454-4251
CSNet:	steve@umcp-cs 	UUCP:	{seismo,allegra}!umcp-cs!steve
USPS: Computer Science Dept., University of Maryland, College Park, MD 20742

kre@ucbvax.ARPA (Robert Elz) (07/07/85)

In article <264@tove.UUCP>, steve@tove.UUCP (Steve D. Miller) writes:
> In article <761@wanginst.UUCP> gill@wanginst.UUCP (Timothy Gill) writes:
> >All of the UNIX documentation I read states that programs and other
> >executable files (shell procedures) are equivalent....
> >                             ......  For a shell procedure to run for
> >those users, there must also be read permission on the file:
> >
> >This is clearly inconsistent. ...
> 
>    I admit that it's inconvenient; maybe someone else has a better
> workaround than the one I use (I rewrite it in C).
> -- 

On 4.2, you can create a new (not used for anything else) group,
and make the shell script setgid to that group (it must be a #!
type shell script).  Then make its permissions be 2751.  (Setgid,
rwx to the owner, rx to the group, and x only to the rest of the
world (everyone bar the owner, as by construction, there is no-one
in the group))

Then the shell will start up in the group of the script, and be
able to open it.  If the process running the script was also
setgid (to a different group) you lose, but apart from that
this works.  (The process remains in all the groups that it was
in, so doesn't lose permission to access any files, and groups
are used for nothing else (file creation group is inherited from
the parent directory))

All set[ug]id shell scripts have security problems, but here
you have nothing much to lose.  All a security cracker here
can get is access to the new group, and all that enables him
to do is read the shell script (or scripts) - which without
this hack he must be able to do to execute them.  So, don't
rely on this to protect secret data in the scripts, but if
all you want it to stop people prying into your horrible sh
(or worse, csh) coding techniques, then it will serve.

This can't work on SysV, as groups are used for file creation,
and there is no such thing as a setgid sh script anyway.

Robert Elz

ps: On 4.3 the '-b' flag must be included on the #! line for the shell.

guy@sun.uucp (Guy Harris) (07/08/85)

Programs and other executable files are not really equivalent; the UNIX
documentation over-simplifies.  The UNIX kernel does the "reading" of
programs (it reads them into a process' address space and then hands control
to the code it read it), and since the kernel is not subject to regular UNIX
permission checking (it enforces those permissions, but since it has the
skeleton key it can open any door it wants to) it can read the file's
contents even if the user doesn't have read permission.  All other
executable files are read by some interpreter which runs in user mode, and
which is therefore subject to UNIX's standard permissions checking.  Because
of that, you can't have an executable file other than a program which can be
executed by a user but not read by that user (unless you modify the
interpreter to run set-UID root and to do its own permission checking).

	Guy Harris

sean@ukma.UUCP (Sean Casey) (07/09/85)

On BSD systems, the kernel can understand that a file is a shell file
and start a shell to interpret it.  It seems that the shell must me able
to read the file to be able to execute it.  I really do not understand why
this is so, since a simple solution would be to have the kernel hand the
shell the file on standard input if --x access is permitted.  The user
would see the execution, but not the source.

This solution seems so simple that I have probably missed a loophole
somewhere.  If not, why don't "they" do it?
-- 

-  Sean Casey				UUCP:	sean@ukma.UUCP   or
-  Department of Mathematics			{cbosgd,anlams,hasmed}!ukma!sean
-  University of Kentucky		ARPA:	ukma!sean@ANL-MCS.ARPA	

guy@sun.uucp (Guy Harris) (07/11/85)

> On BSD systems, the kernel can understand that a file is a shell file
> and start a shell to interpret it.  It seems that the shell must me able
> to read the file to be able to execute it.  I really do not understand why
> this is so, since a simple solution would be to have the kernel hand the
> shell the file on standard input if --x access is permitted.

Unfortunately, this would mean that a shell script couldn't act as a filter;
one of the major improvements that the Bourne shell offered over the V6
shell was that it didn't redirect the standard input of all the programs run
in a shell script to the script, so that you could run a script as a filter.

	Guy Harris

henry@utzoo.UUCP (Henry Spencer) (07/11/85)

> ... a simple solution would be to have the kernel hand the
> shell the file on standard input if --x access is permitted...

Unfortunately, this does not work if the shell file wants to read from
standard input, which many do.  It probably *would* be possible to devise
some sort of standard-file-descriptor convention along similar lines,
but then every interpreter would have to be prepared to accept input that
way.  Actually, this is a weakness even just with standard input; things
like awk are not prepared to read their programs from their input.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

guido@boring.UUCP (07/11/85)

In article <1945@ukma.UUCP> sean@ukma.UUCP (Sean Casey) writes:
>
>        ... since a simple solution would be to have the kernel hand the
>shell the file on standard input if --x access is permitted.  ...
>
>This solution seems so simple that I have probably missed a loophole
>somewhere.  If not, why don't "they" do it?

Simple: the shell's standard input is also the shell file's standard input,
and with your proposed solution the shell script wouldn't be able to read
interesting user data from its standard input, wouldn't be usable as a filter,
etc.  So the contents of the shell file has to be presented to the shell
without closing or dupping the standard input.

	Guido van Rossum, CWI, Amsterdam
	guido@mcvax.UUCP

sean@ukma.UUCP (Sean Casey) (07/18/85)

In article <6503@boring.UUCP> guido@mcvax.UUCP (Guido van Rossum) writes:
>In article <1945@ukma.UUCP> sean@ukma.UUCP (Sean Casey) writes:

>>        ... since a simple solution would be to have the kernel hand the
>>shell the file on standard input if --x access is permitted.  ...
>
>Simple: the shell's standard input is also the shell file's standard input,
>and with your proposed solution the shell script wouldn't be able to read
>interesting user data from its standard input, wouldn't be usable as a filter,
>etc.  So the contents of the shell file has to be presented to the shell
>without closing or dupping the standard input.

Ok, that makes sense.  How about handing the shell an open file descriptor
with the shell script opened for reading?

Sean
-- 

-  Sean Casey				UUCP:	sean@ukma.UUCP   or
-  Department of Mathematics			{cbosgd,anlams,hasmed}!ukma!sean
-  University of Kentucky		ARPA:	ukma!sean@ANL-MCS.ARPA	

gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) (07/21/85)

> Ok, that makes sense.  How about handing the shell an open file descriptor
> with the shell script opened for reading?

?? The shell will open the file specified as an argument, or if that
is omitted, it will take commands from FD # 0 (standard input).
How would opening a file on e.g. FD # 3 do any good?