These comments nearly started a riot. Being of a "System V's ok if you
add quite a lot of Berkeley bits to it" pursuasion, I had a flaming row
with a Sun-freak "Berkeley is best, system V is so broken it's worse than
MS-DOS".
I interpretted the above to mean "setuid/setgid" shells can only be run
by the default shell, and any attempt to change from that results in the
setuid/setgid being ignored.
Consider this example: a root shell script is written by a systems
programmer who thinks tcsh is the best thing since sliced bread (NO
FLAMES PLEASE - I HAVE NOT EXPRESSED AN OPINION EITHER WAY). It needs
to be setuid/setgid for some reason. On most systems tcsh is in
/usr/local/bin, which in many systems is publicly writable to encourage
people to put their ports of PDSoft up. Someone can easily place a
trojan horse in place of /usr/local/bin/tcsh and get root permission.
/bin should never be publicly writable, after all thats what /usr/local/bin
is all about.
He believes that AT&T (or is it Sun - no can't be Sun, he worships the
ground they walk on) have removed all setuid/setgid abilities from all
shell scripts EVER. (PERIOD, FULL STOP, etc).
Which of us is right? Am I being to kind to AT&T, and this is really
broke? Or, is he just overacting because the words System V were
mentioned?
Tell us please, or the wars will continue...
Thanks, Bevis
Disclaimer:
These are my views, many disagree with them, often loudly :-)
Bevis King, Systems Programmer | Email: br...@doc.ic.ac.uk
Dept of Computing, Imperial College | UUCP : ..!mcvax!ukc!icdoc!brwk
180 Queens Gate, London, SW7 2BZ, UK. | Voice: +44 1 589 5111 x 5085
"Never argue with a computer" ... Avon (Blake's 7)
This is the right thing to do for security reasons.
My bias: I'm a Berkeley-phile, I think all AT&T releases after v7 have
sucked. But V.4.0 looks like I'll be able to live with it.
-=- Andrew Klossner (uunet!tektronix!tekecs!frip!andrew) [UUCP]
(andrew%frip.gwd...@relay.cs.net) [ARPA]
In article <4...@gould.doc.ic.ac.uk> br...@doc.ic.ac.uk (Bevis King) writes:
>I interpretted the above to mean "setuid/setgid" shells can only be run
>by the default shell, and any attempt to change from that results in the
>setuid/setgid being ignored. [Someone else] believes that AT&T (or is
>it Sun - no can't be Sun, he worships the ground they walk on) have
>removed all setuid/setgid abilities from all shell scripts EVER. ...
You are both wrong :-)
It was Berkeley; AT&T and Sun will do it (did it in SunOS4.0?) for the
same reason. The set-ID bits on shell scripts are always ignored.
A set-ID binary can, of course, run a shell script, although the
disable in 4.3BSD-tahoe makes this ugly: you have to setre[gu]id first.
There is a large and nasty (but very friendly-looking) bug hiding behind
set-ID shell scripts. The bug is embedded in the file system semantics.
(Actually, I do know how to fix it, even under NFS, though it is not
pretty, and I have never really liked set-ID scripts anyway.)
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: ch...@mimsy.umd.edu Path: uunet!mimsy!chris
> He believes that AT&T (or is it Sun - no can't be Sun, he worships the
> ground they walk on) have removed all setuid/setgid abilities from all
> shell scripts EVER. (PERIOD, FULL STOP, etc).
The current Berkeley distribution (4.3BSD-tahoe) does not allow setuid/gid
shell scripts. The Volume 1, #59 posting to the comp.bugs.4bsd.ucb-fixes
newsgroup (attached) was a change to the kernel to disable them. This is
because there was a security problem associated with shell scripts that we
thought could only be fixed by changing the semantics of shell scripts.
We have since found another method of fixing them, which will require
fairly major modifications to the system, so will probably not be posted as
a bug fix. Setuid/gid scripts should be available in the next BSD release.
Keith Bostic
++++++++++++++++++++
Subject: setuid/setgid shell scripts are a security risk
Index: sys/kern_exec.c 4.3BSD
Description:
Setuid/setgid shell scripts have inherent problems that
may be used to violate security. These problems cannot
be fixed without completely revising the semantics of
executable shell scripts.
Fix:
Panel your office in asbestos, and apply the following patch
to sys/kern_exec.c.
*** kern_exec.c.orig Sun May 22 14:07:19 1988
--- kern_exec.c.new Sun May 22 14:07:55 1988
***************
*** 180,185 ****
--- 180,187 ----
bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname,
MAXCOMLEN);
cfname[MAXCOMLEN] = '\0';
+ uid = u.u_uid;
+ gid = u.u_gid;
goto again;
}
In article <1...@minya.UUCP> j...@minya.UUCP (John Chambers) writes:
>This is something I've been hearing for some time, and wondering when
>the people who understand the supposed security problem are going to
>enlighten the rest of us.
We would rather refrain from shouting it out to the world.
>... I'd sure like to know what it is about the shell programming
>languages ... that make them more risky than a C program.
Nothing in particular. The bug is in the file system semantics. If I
say anything more explicit I feel that it will `give away the store',
as they say. But there is nothing particularly wrong with running a
script while set to some other ID; the problem has to do with running
a script that is itself set-id. You might call it a kernel bug.
Shell scripts probably -- HOPEFULLY -- cannot be suid/sgid. ALLOWING SETUID
SHELL SCRIPTS IS A SECURITY HOLE. It's notable that Berkeley itself has
sent out a "mandatory" BSD patch which disables setuid on "#!" executables.
On the other hand, your Sun-blinded friend is probably incurable. [ 1/2 ;-) ]
++Brandon
--
Brandon S. Allbery, comp.sources.misc moderator and one admin of ncoast PA UN*X
uunet!hal.cwru.edu!ncoast!allbery <PREFERRED!> ncoast!all...@hal.cwru.edu
all...@skybridge.sdi.cwru.edu <ALSO> all...@uunet.uu.net
comp.sources.misc is moving off ncoast -- please do NOT send submissions direct
(But the aliases are NOT on UUNET yet, use the aliases at backbone sites!)
Minor nit: not `allowing' but rather `having', at least in all current
implementations that allow it.
This is something I've been hearing for some time, and wondering when
the people who understand the supposed security problem are going to
enlighten the rest of us.
It's not even obvious that such a claim is credible. As a null
hypothesis, I'd make a fairly obvious suggestion: All programming
languages are equal security risks until proven otherwise.
To be more specific, I'd sure like to know what it is about the
shell programming languages (Bourne, C, K, T, etc...) that make
them more risky than a C program. I don't believe there's anything
magical about C that makes it less a security risk than any other
language. If anything, I'd give more credit to a claim that C
is the dangerous one. I'm sure the the partisans of Ada, not
to mention those of Pascal, Fortran, Lisp, etc., are not too
happy with a claim that C programs are the only ones that can
be trusted to be setu/gid. If that is the claim.
Or perhaps the claim is that interpreted languages are inherently
security risks. Can someone justify this one? It seems false
on its face, as a setuid compiled program can always exec an
interpreter, and the interpreter will then be running under the
setuid permissions.
Or is the suggestion perhaps to make exec*() calls change the
permissions to something unspecified by the execing program?
I'd be a bit surprised if this gains you anything (other than
surprises for unsuspecting super-users who start up a program
that looks like it is setuid to someone else (like uucp), not
suspecting that it will exec a subprocess that will run as root.
I can think of lots of fun things to do on a system that does
this.
Anyhow, enough rambling. Just what is this supposed security bug
that infects setuid shell scripts but not C programs? Why are C
programs more trustworthy? Or is that even the claim? Are Ada
and Lisp programs equally (un)trustworthy? Can you prove it?
[Yes, I know, I'm bound to get a lot of flames telling me what
an incredibly ignorant idiot I am for not understanding it all
without being told. Save your fingers. I've been told that lots
of times before, and more insults won't smarten me up a bit. But
hard information might. ;-]
--
John Chambers <{adelie,ima,maynard,mit-eddie}!minya!{jc,root}> (617/484-6393)
[Any errors in the above are due to failures in the logic of the keyboard,
not in the fingers that did the typing.]
Such a claim is credible. On most UNIX systems supporting "#!"
executables, if that system supports set-UID "#!" scripts, there exists
a program that can, given the existence of a set-UID shell script that
can be executed by user X, permit user X to run any other shell script
set-UID to that user - *regardless* of what the underlying set-UID shell
script does, or what shell it uses! The problem isn't with the language
in which the script is written, it's with the "#!" mechanism itself.
I've seen the program do precisely that.
> To be more specific, I'd sure like to know what it is about the
> shell programming languages (Bourne, C, K, T, etc...) that make
> them more risky than a C program.
Here is a possibly incomplete list of problems:
1. The behavior of shell scripts can depend upon the environment variables
passed in to them. The fix to explicitly set every shell variable
that your shell procedure uses. Explicitly set shell variables to
the empty string rather than assuming they will be initialized to
the empty string by default. More important, explicitly set all shell
variables that the shell refers to implicitly. This includes things
like PATH and IFS.
2. The #! passes the name of the shell script as argv[1], but the shell
does not understand about this convention and will interpret argv[1]
as an option rather than as a file name if the first character of
argv[1] is a minus sign. The fix is to write a little stub program
in C for each setuid shell procedure. The stub program is setuid, and
simply does an exec of the shell with argv[1] set to the full path
name of the actual shell procedure. Since the path name of the shell
procedure is hard coded into the stub, it is guaranteed not to start
with a minus sign. The file containing the shell procedure should not
be either setuid or executable, to ensure that all user invoke the
stub rather than running the shell procedure directly.
Aside from problems 1 and 2, there are also some more general issues:
3. People tend to use the shell for quick hacks which work right in most
cases. But being a little bit insecure is like being a little bit
pregnant. The fix is to put as much thought into writing a setuid
shell procedure as you would into writing a setuid C program. In fact,
writing a setuid shell procedure is *more* difficult that writing a
setuid C program because the semantics of C are simpler.
4. When you write a shell procedure your code depends upon a large body
of software: the shell and also all the programs that your shell
procedure invokes. These programs change. Usually the changes are
backward compatible enough for most purposes, but they may not achieve
the level of backward compatibility required to preserve the security
of a setuid shell script. For example, csh doesn't have IFS. If IFS
were added to csh, most csh shell scripts would continue to work, but
setuid csh scripts would have to be modified to set IFS to a standard
value. The fix is to write setuid programs in C.
OK, that last sentence deserves half a ":-)", but most of the time it's
not worth the trouble to write a setuid program as a shell procedure when
you have C available. An exception is when you need to invoke an operation
(such as ps(1)) which requires you to run a separate program. This is
enough of a pain to do without the shell (note that popen invokes the shell)
that I might use a setuid shell procedure.
In any case, this discussion started with the claim that System V Release 4
would ignore the setuid bits when interpreting "#!". This affects various
interpreted languages like ICON, but as I explained in point 2 above, setuid
shell procedures implemented using a C language stub (which is the only way
I know of to implement setuid shell procedures if you want securely) don't
use the #! facility at all.
Kenneth Almquist
Or, if the script is a Bourne shell script, put
#! /bin/sh -
rather than
#! /bin/sh
as the first line. This causes the shell to be passed a "-" as an
argument before the script name; all versions of the Bourne shell that I
know of will stop processing option arguments when they see the "-".
I think the same applies to the Korn shell.
If it's a C shell script, the fix is to 1) get a version of the C shell
on your system that supports the "-b" flag (like the 4.3BSD C shell
does; SunOS, for instance, has had that since 3.2), and put
#! /bin/csh -b
as the first line. "-b" has much the same effect.
If it's neither a C nor a Bourne nor a Korn shell script, you're on your
own.
Note also that there's another problem with the first character of the
script beginning with "-"; this problem was fixed in 4.3BSD's kernel,
and that fix was in SunOS since 3.2 as well.
Nevertheless:
1) there is another problem with the "#!" mechanism that makes
set-UID scripts insecure; it is not a problem with a
particular shell, so it potentially affects all shells
and
2) even if you fix that (there are ways to fix it if your kernel
has a certain mechanism, which unfortunately most don't have,
yet), the other arguments against set-UID scripts still apply
- you're relying on a large, complicated piece of software,
namely the interpreter running your script, and there may be
sneaky little back doors like IFS that you don't even know about.
It's hard enough to make sure a C program is secure when run set-UID....
The other is the general problem with setuid shell scripts: the semantics
of the shell are quite complex and there is little control over low-level
details, which makes it relatively difficult to write cracker-proof shell
scripts. This problem is solvable in principle, but it's one of those
cases where there have been so many problems found that nobody is at all
confident that there aren't any more.
--
The meek can have the Earth; | Henry Spencer at U of Toronto Zoology
the rest of us have other plans.|uunet!attcan!utzoo!henry he...@zoo.toronto.edu
Although I fully believe that setgid/uid shell scripts are a security
hole why would the kernel enforce this? All setid programs are a
potential security hole and generally only very careful wizards can
assure reasonable safety, no one can make security programming
"user-friendly", at least not without generally castrating the system.
Not allowing me to create a setid shell script seems to assume that I
am a) interested in security on this particular machine (eg. my home
unix system or other personal workstation only I can log into anyhow)
and b) that I am too stupid (but not stupid enough) to defeat this
questionable "feature" by setuiding a C program which just does a
system() or other exec*() of the script.
Or am I missing something here and the hole is open to non-priv'd
users such that they can attain root (or similar) status even tho I,
as root, have not created any setuid/setgid scripts on my system? If
so then I could go along with the above fix if no reasonable
workaround to that problem can be thought of. The only holes I am
aware of either involve the existence of a priv'd script created by a
priv'd user or remote file system hacking which is just as open to any
programming, not just shell scripts.
-Barry Shein, ||Encore||