[comp.bugs.sys5] Bug in tempnam

friedl@mtndew.UUCP (Stephen J. Friedl) (06/04/90)

Once again we find another library function that uses access(2)
in the wrong way.  Tempnam(3), called with

	char *tempnam(dir, pfx)
	char	*dir, *pfx;

makes a temp file name in the mentioned directory with the given
prefix and returns it.  If the directory suggested by the user is
not available, /tmp is used as a last resort (although I have
seen /usr/tmp used too).

Imagine writing an lp spooler and the "lp" command takes stdin.
The program might do something like:

	fname = tempname("/usr/lp/temp", "d-");

assuming that the filename will be built in the suggested place.
If the lp command is setgid lp *and* the underlying user cannot
write to /usr/lp/temp (but presumably the lp gid can), the file
will get stuck in /tmp or /usr/tmp.  Now reboot your machine and
watch your print request disappear.

Please, everybody, if you think that access is a handy does-the-
file-exist function you are very wrong, and it's a safe bet that
it does not belong.  Email will get a pretty detailed note on why
access(2) is evil.

     Steve

-- 
Stephen J. Friedl, KA8CMY / Software Consultant / Tustin, CA / 3B2-kind-of-guy
+1 714 544 6561  / friedl@mtndew.Tustin.CA.US  / {uunet,attmail}!mtndew!friedl

"I will defend to your death my right to my opinion" - me

6sigma2@polari.UUCP (Brian Matthews) (06/06/90)

In article <433@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes:
|Email will get a pretty detailed note on why
|access(2) is evil.

I wouldn't go that far.  Access(2) is quite necessary for certain things.
Unfortunately, it could probably have a better name, and the manual page
(at least all the ones I've seen) doesn't do a great job of indicating
when it should and shouldn't be used, so lots of people (evidently
including whoever wrote tempnam(3) :-)) misuse it.  This doesn't mean
that access(2) is evil though.

Remember: Access(2) doesn't kill people, people kill people :-)
-- 
Brian L. Matthews	blm@6sceng.UUCP

del@thrush.mlb.semi.harris.com (Don Lewis) (06/07/90)

In article <2077@polari.UUCP> 6sigma2@polari.UUCP (Brian Matthews) writes:
>In article <433@mtndew.UUCP> friedl@mtndew.UUCP (Stephen J. Friedl) writes:
>|Email will get a pretty detailed note on why
>|access(2) is evil.

Would using stat(2), and checking if the uids/gids match and looking
at the permission bits have been better?  Should the effective or
real ids have be used?

>
>I wouldn't go that far.  Access(2) is quite necessary for certain things.
>Unfortunately, it could probably have a better name, and the manual page
>(at least all the ones I've seen) doesn't do a great job of indicating
>when it should and shouldn't be used, so lots of people (evidently
>including whoever wrote tempnam(3) :-)) misuse it.  This doesn't mean
>that access(2) is evil though.
>

I agree that access(2) is very useful.  I have seen a lot of objections
to its use in programs because of what how it interacts with set[ug]id'ness,
but all the examples I have seen have are not (and have no business
being) set[ug]id.  Even if a program is set[ug]id, I believe that
access(2) is still very useful, because it returns the file accessability
for the actual user running the program (assuming the program doesn't
fiddle with the real [ug]id).  For example, if a setuid root program
which uses access(2) to check for valid write access to a file before
fopen()ing it for writing will not overwrite any files that the user
does not actually have write permission for.

Using access(2) propery in a set[ug]id situation is a bit tricky, and
should be better documented.  Any library routines that use access(2)
or other validation methods should be documented as to exactly how they
behave.  The proper validation method depends on the circumstances.
--
Don "Truck" Lewis                      Harris Semiconductor
Internet:  del@mlb.semi.harris.com     PO Box 883   MS 62A-028
Phone:     (407) 729-5205              Melbourne, FL  32901