This is the mail archive of the
mailing list for the glibc project.
Re: Revisiting O_SEARCH and O_EXEC
- From: Rich Felker <dalias at aerifal dot cx>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>
- Cc: Christoph Hellwig <hch at lst dot de>, libc-alpha at sourceware dot org
- Date: Mon, 5 Aug 2013 17:41:02 -0400
- Subject: Re: Revisiting O_SEARCH and O_EXEC
- References: <20130802173236 dot GA2491 at brightrain dot aerifal dot cx> <Pine dot LNX dot 4 dot 64 dot 1308042134580 dot 25359 at digraph dot polyomino dot org dot uk> <20130805081947 dot GA5797 at lst dot de> <20130805121139 dot GE221 at brightrain dot aerifal dot cx> <Pine dot LNX dot 4 dot 64 dot 1308051701070 dot 15287 at digraph dot polyomino dot org dot uk> <20130805172658 dot GK221 at brightrain dot aerifal dot cx> <Pine dot LNX dot 4 dot 64 dot 1308052108120 dot 19563 at digraph dot polyomino dot org dot uk>
On Mon, Aug 05, 2013 at 09:14:27PM +0000, Joseph S. Myers wrote:
> On Mon, 5 Aug 2013, Rich Felker wrote:
> > I've emailed LKML about this but gotten no response. Perhaps I should
> > try that linux-api mailing list. What is the address for it?
> email@example.com (it doesn't tend to be very actively used).
OK, I'll write up something to send to them with citations of this
thread and my past post to LKML.
> > > It's not clear glibc should try to do any better than the kernel regarding
> > > graceful failure modes in the absence of kernel support (that is, for
> > > glibc to try to give accurate ENOSYS or similar errors when the kernel
> > > support needed for the proper semantics of a given O_* flag isn't present,
> > > when the kernel practice is to ignore unknown flags, and in general the
> > > user may wish to pass through values unknown to glibc when their kernel is
> > > newer than their glibc). Universal practice in glibc is that header
> > > values are defined and functions declared for features in the newest
> > > kernels even though the kernel in use at runtime may not support them.
> > Historically glibc has emulated a lot of things on older kernels (at*
> > functions, per-thread cpu clocks, etc..) as well as things not even
> > supported by the kernel (like euidaccess). Some of these emulations
> > have been very poor-quality, but I believe O_SEARCH and O_EXEC are
> > trivial to do 100%-correctly, so I don't see any good justification
> > for omitting them. Moreover, like I said, the kernel folks do not seem
> > receptive to adding functionality specific to the POSIX definitions of
> > these access modes in kernelspace...
> It's not at all clear to me they can be done 100%-correctly in the absence
> of O_PATH kernel support.
The kernels without any O_PATH support at all are getting really old.
In at most a few more years glibc will probably be ready to drop
support for them. With the emulations I came up with (using /proc),
even the oldest, most broken O_PATH support works.
> In particular, undesired side effects from
> opening a device without O_PATH can't be avoided (without races) in any
> way I can see
Indeed; I have no idea why the kernel did not add O_NODEV ages ago...
We should check the side effects of opening a device with mode 3. I
suspect they still exist, but if mode 3 did suppress the worst side
effects, that might be a solution. For O_SEARCH, adding O_DIRECTORY is
an option, but I'm not sure if chording it onto O_SEARCH would be
okay, since fcntl would not be able to return back the same value, and
O_ACCMODE would then have to include a flag bit in the access mode
mask. If it's not chorded onto O_SEARCH, open() has no way of knowing
whether the caller wanted O_SEARCH or O_EXEC and thus can't add its
own O_DIRECTORY flag.
In any case, emulation of O_SEARCH and O_EXEC on pre-O_PATH kernels
will be at least minimally imprecise due to lack of support for
opening non-readable files. I'm not clear on whether the device open
issue is even a conformance or safety issue, though. I don't see
anywhere in POSIX where it mandates that calling open with O_SEARCH or
O_EXEC on a device node should not have side effects on the device. In
fact the result of applying O_SEARCH to a non-directory is
unspecified. I raised this issue with the Austin Group -- that there
are race conditions with files of different types being put in place,
and thus that some safety guarantees are needed rather than complete
unspecified or undefined behavior when the wrong access modes or flags
are used. However, I think the real issue is that programs need to
avoid opening anything in a pathname where some components are under
the control of untrusted users unless they're using O_NOFOLLOW. This
is not unique to O_SEARCH and O_EXEC; it applies to all access modes.
> (and my point is that security issues arising from O_SEARCH
> and O_EXEC in this case should be considered to be instances of the same
> security issue as if the user directly passes O_PATH, which comes from the
> kernel choice not to give errors for unknown O_* flags, and that we
> shouldn't specially try to reject any of the three flags in userspace in
> that case any more than we try to validate other O_* flags passed to the
> kernel for the possibility that an old kernel may not implement all the
> desired semantics and so security issues may arise).
Indeed, I don't think userspace workarounds are needed here. O_RDONLY
is an acceptable partial implementation of O_SEARCH or O_EXEC on old
kernels, and it is no more of a security risk than opening files in
untrusted paths is to begin with. Programs that would be targets for
attack should avoid untrusted paths or use O_NOFOLLOW.