Date: Sun, 01 Apr 2001 10:55:23 +1000 From: Greg Black <gjb@gbch.net> To: Robert Watson <rwatson@FreeBSD.ORG> Cc: Bill Moran <wmoran@iowna.com>, freebsd-hackers@FreeBSD.ORG Subject: Re: Security problems with access(2)? Message-ID: <nospam-986086523.86272@maxim.gbch.net> In-Reply-To: <Pine.NEB.3.96L.1010331173532.40815M-100000@fledge.watson.org> of Sat, 31 Mar 2001 17:39:31 EST References: <Pine.NEB.3.96L.1010331173532.40815M-100000@fledge.watson.org>
next in thread | previous in thread | raw e-mail | index | archive | help
Robert Watson wrote: | On Sun, 1 Apr 2001, Greg Black wrote: | | > There is only one reason to use access() and that's to discover if a | > file is accessible. Because of the race condition and the fact that | > access() tells lies to setuid and setgid programs, it is both dangerous | > and useless unless used with such care that any benefits it provides are | > lost in the noise. | | Actually, there are a number of legitimate reasons that a program might | wish to determine the accessibility of a file. This is quite true. My point was that access(2) is not the right hammer for this nail. | However, in my view | access(2) is mis-specified. Really, I would like it to generate results | based on the effective uid and gid of the process, not the real uid and | gid, so it could allow applications to defer to kernel policy for | accessibility when generating output for the user. However, instead it | uses the real uid and gid in a manner likely to induce races. Many years ago I implemented a new interface that I called eaccess() which replicated the work of access, but tested against the effective uid and gid. I'd like to see that introduced more widely. | The | scenario for access(2) that I have in mind would be for GUI's that want to | display (for example), a read-only version of an icon. Deriving the | read-only status from the results of stat() (and friends) means | replicating the kernel protection policy in userland, which breaks for | ACL-enabled, MAC, BSD file flags, capability, superuser, DTE, ... | environments. I.e., the userland process cannot adequately determine its | access rights to a file purely based on available output from stat(), and | really shouldn't try. Agreed, and this is why something like access() that did a "better" job would be useful. | Unfortunately, access(2) does the wrong thing. :-) | However, access(2) is defined in some or another spec, possibly SUS or | POSIX. I'm pretty sure we've had access(2) since Version 7. And it has been part of POSIX for at least 10 years. And my POSIX book says: Some historical implementations of access() do not check the file's access correctly when the real user ID of the process is the superuser. In particular, they indicate that the file may be executed without regard to whether the file is executable. The standards allow this behavior. That final sentence is the kicker for me -- access(2) is defined in a broken manner as well as inviting race exploits and telling lies to set{u,g}id programs. And note that the FreeBSD man page says: Even if a process has appropriate privileges and indicates success for X_OK, the file may not actually have execute permission bits set. Likewise for R_OK and W_OK. All this adds up to a general statement that access() should be shunned completely. If people need this kind of functionality, they should think hard about it in the following terms: * If there's any way to accomplish their goals by just doing the operation of interest (e.g., open(2) the file), then that's by far the best solution. * If the general functionality of access(2) is really needed, they should use a new function that performs the job of access() with the following changes: - perform the tests against the effective uid and gid - perform the tests so that they only return true if the file really is executable, etc. - take into account all relevant factors: read-only file systems or media, file flags, file permissions, any other ACLs, etc. I guess this is really off-topic for hackers (although it seems more interesting to me than the drivel in the threads started by dennis@etinc.com). To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?nospam-986086523.86272>