[cap-talk] Designation linux kernel patch concept
David Hopwood
david.hopwood at industrial-designers.co.uk
Tue Dec 4 20:03:00 EST 2007
Mark Seaborn wrote:
> David Hopwood <david.hopwood at industrial-designers.co.uk> wrote:
>
>> It seems to me that using fds as (essentially) capabilities for files
>> does not quite work, because:
>>
>> - an fd to an open file can't be safely used to designate the file
>> itself, if duplicates of the fd are to be shared between processes.
>> That is because the duplicates share attributes that you don't want
>> to be shared, such as the O_NONBLOCK flag (see
>> <http://plash.beasts.org/wiki/UsefulKernelChanges>
>> and <http://lkml.org/lkml/2007/8/14/135>).
>
> I've discovered that you can use /proc/self/fd/N to re-open a pipe FD
> and that gives you another FD on which O_NONBLOCK can be set
> independently. That's not ideal for the use case I had in mind
> (http://plash.beasts.org/wiki/EventLoopAndFDs) because you would have
> to treat file FDs and pipe FDs differently -- re-opening a file FD
> would give you an FD with an independent seek position -- and I'm a
> bit relucant to change behaviour based on the FD type reported by
> fstat().
>
>> - there is no fd type that designates just a file inode.
An FD with an independent seek position and independent O_NONBLOCK
is a good approximation of this (even if having to re-open the FD
is not ideal for other purposes). So I'm happy to see that I was wrong --
it is possible to share FDs representing files safely between processes,
albeit with some limitations as you point out below.
> You can open a file and use the resulting FD to re-open the file using
> /proc/self/fd/N. Most operations available through pathname-based
> calls can also be done on file FDs -- assuming you can acquire the FD
> in the first place (eg. you can't do an lchmod() by doing open() +
> fchmod() if the file has its permissions bits unset to start with).
>
> If /proc isn't directly available (as under Plash) you could have a
> trusted intermediary for /proc that re-opens an FD if you asked for a
> subset of the file mode flags.
>
> That doesn't work for inodes that are not files such as Unix domain
> sockets though.
>
>> - to do system call interposition in a way that is safe against
>> race conditions, you *really* need an fd type that designates a
>> file inode.
I should have said, you really need it in general, to implement arbitrary
security policies. You don't necessarily need it to implement any
particular policy.
>> Let's say that you are interposing on one of the "at"
>> calls, and you do a security check based on the dirfd and the
>> relative path. The check passes, so you forward the call to the
>> kernel. But how do you know that by the time the kernel
>> interprets the dirfd and path, it is pointing to the same file?
>> You don't. As pointed out in
>> <https://db.usenix.org/events/woot07/tech/full_papers/watson/watson.pdf>,
>> such race conditions are quite exploitable in practice.
>
> What sort of checks do you have in mind?
Any that might be needed for an AppArmor policy (e.g. see
<http://www.linuxconf.eu/2007/papers/Arnold.html>), or more generally
that the author of a Linux Security Module might want to enforce. Also
see the examples in section 7 of 'watson.pdf'. I wasn't intending to
limit this argument to checks that would be needed to implement a
capability system (if any explicit checks are needed in that case).
> The main problem Plash faces
> in this area is doing operations relative to a dir FD without
> following symlinks. connect() on Unix domain sockets is the main
> problem here because there is no way to switch its symlink-following
> off (http://plash.beasts.org/wiki/PlashIssues/ConnectRaceCondition).
Right, and there's no '[f]connectat'. But this is a slightly different
issue to the one above, which Plash avoids by not having to do any
explicit checks that depend on the path (I think).
>> However, the "at" calls don't have the right interface to be used with
>> an inode fd. It would be bordering on insane to add yet another set of
>> API calls and/or syscalls (and it would beg the question, "how many
>> more iterations will we need to get this right?").
>
> Yes, Linux seems to be facing the problem at the moment having
> pressures to add interfaces but without having a good framework for
> doing so. Now if only they had some sort of generic object invocation
> interface... :-)
Tanenbaum was right all along ;-)
--
David Hopwood
More information about the cap-talk
mailing list