Subject: Re: Addition to force open to open only regular files
To: NetBSD Kernel Technical Discussion List <tech-kern@netbsd.org>
From: Matthew Orgass <darkstar@pgh.net>
List: tech-kern
Date: 11/24/2000 04:27:16
On Fri, 24 Nov 2000, Greg A. Woods wrote:
> [ On Thursday, November 23, 2000 at 18:19:03 (-0500), Matthew Orgass wrote: ]
> > Subject: Re: Addition to force open to open only regular files
> >
> >   This is not true.  In fact, setre[ug]id offers two features not
> > available otherwise: 1) root-started programs can pretend they were
> > started by another user and/or group,
>
> This has always been possible, from day one, with setuid(getuid()).

  Only if the binary is not setuid, although I guess if it is you could
achieve the same thing with an extra exec unless the program is not usually
setuid (which might never really be valid).

> > but #2 should have been done by
> > simply allowing setuid to the effective user id (so they are never
> > swapped) and not allowing non-root users to access setreuid.
>
> setuid(geteuid()) is in effect a no-OP [unless some other set*id() call
> has already intervened], except that it doesn't affect the real-IDs.

  Right, but dropping the privilege of the real-ID is hardly a no-op.
Ah, I see this could be done with an extra exec too.

  Ok, so setre[ug]id just allow you to save an exec.  Still, it adds
little possible use to an already quite abuseable mechanism while allowing
you to do what you mean in a more direct manner.

> >   Both switching to the real id and open_as do not really fix the problem
> > because the id of the user who execed the program may no longer be
> > available at all, as in the case of the user program that effectively does
> > setuid(geteuid()).
>
> I'm not sure which list my message explaining why this does not matter
> was posted to, but please understand that this does not matter.  If a
> set-ID program calls setuid(geteuid()) [or otherwise passes the
> effective-UID to setuid()] then this can only be because the program
> has, as you say pretend, to take on the effective-ID in such a way that
> it is impossible to know that it was not initially started by the user
> to whom the set-ID program is owned.

  This is true except for the environment, which is still tainted or not
depending on what you did or did not do previously.  Opening as the real
user id just changes (or specifies) the documented behavior;  it does not
actually fix anything.  While you can argue if the real id should be used
or not, it does not address the real issue that tainted data is being
used.

> >  Furthermore, checking for setuid does not fix the
> > problem because the program could then exec another program, keeping the
> > same environment, that then uses the tainted envrionment variable (this
> > kills file-id).
>
> Exactly, which is why saved-set-ID swapping must be completely disabled,
> since doing so will make it easier for a set-ID program to permanently
> avoid passing a potentially dangeous environment on to some unsuspecting
> non-setuid program.  This is, of course, because it will be easier for
> set-ID programs to decide to permanently drop their privileges as soon
> as they possibly can.

  It is just as easy to permanently drop privileges now.  Removing saved
ids only make it impossible to temporarily drop privileges and do not
change the fact that the environment must be untainted while in the higher
privilege.  But if you can temporarily drop privileges, then you should
always run in the lower privilege except for the exact places where you
need the higher privilege.  In this case, opening files specified in
environment variables would be done as the real user even if done as the
effective id.

> >  Disallowing library functions from accessing devices does
> > not work when the kernel does not know that a file refers to a device (as
> > could be the case on a network file system).
>
> Well, actually, any network file system which permits opens of devices
> must clearly identify the fact that the file is a device to the client
> kernel.  If this is not so then the remote filesystem in question is
> extremely buggy and untrustworthy in the first place.

  Why?  The UNIX model designed devices to appear to be files that may
have a few extra capabilities.  If these capabilities are not needed, then
the only reason a kernel would need to care that it was a device was to do
something special just because it was a device.  But you don't care if it
is a device or not, you care if it has side effects, which with modern
file systems might be the case with any file.

> >   The real problem here is not considering the environment to be tainted.
>
> Yes of course -- this is one of the top ten rules for set-ID programmers
> to be aware of.  The problem here is not that this is a new issue, but
> rather that several extremely popular standard library routines have
> made use of environment variable values as filenames and such routines
> are almost impossible for at least some classes of set-ID programs to
> avoid.  Since such set-ID programs do not explicitly sanitise their
> environment, and since doing so would anger at least some users, another
> solution is cried out for.

  There is no other real solution: the environment must be untainted.
While opening as the real id may help achieve that goal, it does not by
itself solve the problem.  Further, file activity is not necessarily the
only problem with the use of a tainted environment: anything that can
alter the behavior of the program (or other programs acting for it) in
ways not known by the programmer can potentially be a security problem.

> > One way to make this clear is to start setuid programs with an empty
> > environment and an additional tainted environment that contains the
> > environment passed to execve.
>
> And some people thought what I was proposing would be controversial!
> You've just thrown in the towel, I think!  :-)

  I don't think this would be at all unreasonable and would be much easier
to adapt to than some of the things you have proposed which change the
basic setuid model.  Unlike the other proposals, this requires the
programmer to notice the real problem.  If they still ignore it, they
deserve to loose.

> I believe though that removing saved-set-ID swapping and in its place
> offering a truly safe way for even a library routine to open any
> arbitrary file with just the real-ID credentials will mitigate the
> potential dangers such that an exploit attempt can be discovered before
> it can be taken advantage of.

  Saved-set-ID provides this, it just isn't being used.

  Any effort directed to setuid security should be concentrated in the
following areas:
1) Preventing the use of tainted data
2) Pinpointing exact areas where higher privilege is needed
3) Documenting all of the above

  The use of tainted data will eventually loose no matter how many hoops
you jump through.

Matthew Orgass
darkstar@pgh.net