Subject: Re: Addition to force open to open only regular files
To: NetBSD Kernel Technical Discussion List <tech-kern@netbsd.org>
From: Greywolf <greywolf@starwolf.com>
List: tech-kern
Date: 11/24/2000 13:15:07
On Fri, 24 Nov 2000, Greg A. Woods wrote:

# [ On Friday, November 24, 2000 at 04:27:16 (-0500), Matthew Orgass wrote: ]
# > Subject: Re: Addition to force open to open only regular files
# >
# >   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.
# 
# It certainly does fix the major problem here!  Normal users are not
# permitted to open things like rewind-on-close tape drives, so using

...Can I see your intergalactic passport, please?

Do you not consider mortals in group 'operator' to be "normal users"?
[if not, explain...]

# open_as() in the library to open $TZ or $HOSTALIASES would prevent users
# from clobbering backups or whatever.

I'm wondering:  Why isn't fhopen() modified to check existing permissions
before returning the descriptor?  getfh() doesn't appear able to bypass
hierarchy permissions at random; all fhopen() does is guarantee that it'll
return a descriptor to the file in question if it still exists.

# It matters not if the data's tainted as long as the user can only do
# damage to his or her own files.  I.e. it's arguable if you could even
# claim the env var's contents are "tainted" in that case -- they might
# not be valid, but they're not dangerous (to the system) any more.

Now it's a matter of semantics; the argument has taken the tack of
"would you sleep with me for a million dollars?".

The more I look at it, the less inclined I am to see that open_as()
has any real merit.

I've seen three problems here and we're trying to address all of them
with a brick.

1.  How to prevent a normal user from opening any file when a program
    is given super-user privileges?

2.  How to avoid using tainted data in a misdirected fashion?

3.  How to avoid opening a different file than was originally intended.

open_as() is attempting to Be The Brick.

# >   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.
# 
# The *ONLY* gain in running with temporarily lowered privileges currently
# is that you don't have to remember to drop them before calling any
# system call which might make use of the process' effective-ID
# credentials (and since this can happen inside library routines this
# means the set-ID programmer doesn't have to be 100% familiar with all
# such library routines).  Unfortunately does not prevent a buffer
# overflow or printf format string exploit from regaining those privileges
# and starting a root shell or whatever.

The hacker in question has to be intimately familiar with
	- what's enabled in your kernel
	- what version of which os you're running
	- the machine architecture in question

in order to regain those privs since the only way to do that is to fake
a syscall or find a way of mangling the stack pointer into the address
space.

Redesigning the paradigm is not going to help; seems to me
more of a hindrance, actually.
	

# >   There is no other real solution: the environment must be untainted.
# 
# Why?  So long as code that parses environment values is robust, and so
# long as any access to files they might specify id done as the real user,
# there's no real danger even if the environment is full of garbage values.

Typically, in set-id code, one programs around the supplied environment
and doesn't allow much of anything in.  I will note that login and su
seem to be exceptions to this rule under *BSD; under Solamis, the PATH
gets reset under both (which is kind of bogus, in a way, because then
if you do 'su user "command", you have to remember to provide a suitable
path if it's to work).

# > While opening as the real id may help achieve that goal, it does not by
# > itself solve the problem.
# 
# What problem are you trying to solve?

Is *any*body clear on this at all?  Given the three problems above, I
don't see one clear direction toward any of them.

# The set-ID programmer must always be aware of all potential security
# problems and all ways that the user might potentially affect the
# operation of his or her program.

...further reducing the need for open_as.

# Of course this is only an ideal and sadly it is not reached all of the
# time in all existing set-ID programs.

Then there's some learning to do! :-)

# However, as Mr. Elz has said about tzfile parsing, code that's broken
# and not robust enough to avoid crashing when handling garbage data is
# presented to it must be fixed!

it is definitely the responsibility of the programmer to make sure that
the code in question is valid.

# >   Any effort directed to setuid security should be concentrated in the
# > following areas:
# > 1) Preventing the use of tainted data
# 
# Or fixing the code that can't deal with it robustly....
# 
# > 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.
# 
# Why?

Well, I don't agree with the 'no matter how many...' part, but...
That's the definition of tainted data.  If you examine it and determine
it to be sane, pass it through.  If not, don't.  But if you just
willy-nilly toss it about, it will ultimately make your program sick.

If you're trusting the user to provide you data, double-check its
sanity ANYway.  I bet the earliest versions of chfn/chsh REALLY mangled
the password file, for example.

If one of the hoops you can jump through is called a data integrity
check, then we can make this whole thing work as is.
If it's just a myriad of specialized system
calls and a paradigm shift, then I think we're barking up the wrong tree.

				--*greywolf;
--
"I didn't get where I am today without using BSD."