Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Oct 2002 10:01:30 -0400 (EDT)
From:      Chris BeHanna <behanna@zbzoom.net>
To:        FreeBSD Security <security@freebsd.org>
Subject:   Re: access() is a security hole?
Message-ID:  <20021011094935.I86274-100000@topperwein.pennasoft.com>
In-Reply-To: <20021011185423.B12227-100000@gamplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 11 Oct 2002, Bruce Evans wrote:

> On Thu, 10 Oct 2002, David Schultz wrote:
>
> > Thus spake Peter Jeremy <peter.jeremy@alcatel.com.au>:
> > > On 2002-Oct-08 17:23:35 -0400, The Anarcat <anarcat@anarcat.ath.cx> wrote:
> > > >Also, this means that the stat() manpage should also contains a
> > > >similar section about its non-fd incarnations.
> > >
> > > I disagree.  access(2) is specifically designed to allow setuid/setgid
> > > programs to validate access rights based on the real uid/gid - but is
> > > virtually impossible to use safely for this task because of the
> > > inherent race conditions.
> >
> > No, access(2) is designed to allow NON-setuid programs to easily
> > do sanity checks without opening a file or device right away.
> > There's still a race condition, but it isn't typically a security
> > threat when all you're trying to do is prevent the user from
> > shooting himself in the foot.  To use access() in a setuid program
> > is usually an error.
>
> No, it was designed to be useful to setuid programs.  Whether it
> actually is useful is arguable.  From the V7 manual:
>
>     "The user and group IDs with respect to which permission is checked
>     are the real UID and GID of the process, so that this call is useful
>     to set-UID programs".
>
> Setuid programs should only use access() to check whether they will
> have permission after they set[ug]id() to the real [ug]id.  Non-setuid
> programs mostly don't need such checks.  They can just try the operation.

    Perhaps the way to avoid the race is to open the file, lock it,
and *then* call access(), then close the file or proceed based upon
the result.

    Yes, I know--there's a possible race between open() and fcntl().
Where there a way to get a mandatory readlock on a file without
opening it, then that race would be removed.  Or, perhaps a more
workable solution is to add a flag to open() that locks the file at
the same time it's opening it.  I don't have time at the moment to
look at the source to see how this might be implemented, but I think
it's a reasonable idea.

    Once a process has the lock, it can call fstat() to determine if
the real [ug]id (which it already knows) has permission to access the
file in the desired manner.  If not, close the file (implicitly
dropping the lock).  This whole mess should be encapsulated into its
own procedure.

    For programs that modify ranges of a file, the interface gets
slightly more complicated, as you need an flock structure to specify
the range to lock (so that other processes aren't blocked by a
whole-file lock).

    For those who are (justifiably) skittish about modifying open(),
perhaps a new syscall with semantics such as open_and_lock() should be
created.

-- 
Chris BeHanna                      http://www.pennasoft.com
Principal Consultant
PennaSoft Corporation
chris@pennasoft.com


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-security" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20021011094935.I86274-100000>