Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sun, 28 Aug 2016 12:20:37 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: Re: readdir(3): behavior on descriptors with O_SEARCH

On Sun, Aug 28, 2016 at 07:02:18PM +0300, Dmitry Selyutin wrote:
> Hi Rich,
> 
> thank you for the detailed answer!
> 
> > If a program is doing this then trying to fdopendir/readdir, it's a
> > bug in the program. A directory opened with O_SEARCH is only usable
> > for search (attempting to access a file/directory in that directory
> > by name, using one of the *at functions) not for reading. Unix has
> > always distinguished search (+x) and read (+r) permission for
> > directories and O_SEARCH vs O_RDONLY is similar.
> Well, that's probably the worst kind of bugs, since it was caused by
> misinterpretation of the documentation.
> That was written intentionally due to misunderstanding, so I really want to
> clarify the situation here.
> So does it mean that descriptors opened with O_SEARCH are usable only for
> *at functions?
> I've been under the impression that it's part of the O_PATH functionality,
> not O_SEARCH.

http://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html

	O_RDONLY
	Open for reading only.

	...

	O_SEARCH
	Open directory for search only.

Note the word "only". Moreover it's clear from the permissions model
that you can't read from a directory opened for O_SEARCH, since
O_SEARCH does not require read permission; permission enforcement is
specific in the errors (and possibly elsewhere):

	[EACCESS]
	Search permission is denied on a component of the path prefix,
	or the file exists and the permissions specified by oflag are
	denied, or the file does not exist and write permission is
	denied for the parent directory of the file to be created, or
	O_TRUNC is specified and write permission is denied.

The relevant part of this text is "or the file exists and the
permissions specified by oflag are denied". If you could read from a
fd opened for O_SEARCH, you could bypass the check for "r" permission
at the fs level and read any directory to which you had "x"
permission. (In a sense you can do this anyway by brute-force search,
but that does not work when filenames in a +x-r directory are
sufficiently long and unpredictable, which is the case for secure uses
of +x-r.

> > It's been an ongoing fight even trying to get the kernel to reserve a
> > bit number for them. It looks like the correct course of action (the
> > one that's compatible with their non-action) is going to be using
> > O_PATH|3 for both of them. This allows userspace open to process
> > O_SEARCH and O_EXEC slightly differently from O_PATH (O_NOFOLLOW has
> > different semantics) and the kernel will ignore the extra access mode
> > bits with O_PATH anyway.
> At the same time, if I understand you correctly, you mean that O_PATH is a
> different beast than O_SEARCH.

Linux implemented O_PATH independently of POSIX O_SEARCH and O_EXEC,
not specifically with the intent to model them but rather to allow
more general things.

> I've found a mail in the DragonFly mailing list, which also slightly
> touches this topic[0].
> They also propose to use value 3 as currently unused value; I don't know if
> it is implemented yet.
> FWIW, neither OpenBSD nor FreeBSD provide O_SEARCH flag; the latter
> provides O_EXEC though.

Linux actually uses the value 3 for a wacky purpose: ioctl-only
opening of certain device nodes. Opening with mode 3 requires +rw
permissions. This was a huge waste of the value but I think they feel
obligated to keep it for compatibility.

> I finally have a good access to the Internet so I managed to find a
> detailed discussion on this topic[1].
> Sorry guys (and especially you, Rich) that I didn't find it before; it
> would have saved some questions earlier.
> 
> Rich, could you please elaborate on the exact semantics of O_SEARCH flag?
> Again, thank you very much for your answer and for your patience!

My understanding is that you can use an O_SEARCH fd for the *at
functions and in any place where an operation is just being performed
on the fd (like fstat, fchown, etc.) where the open modes are not
relavant (e.g. fchown does not use the mode the file was opened with
but checks permissions at the time of the fchown). You definitely
cannot use it for read or write operations.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.