tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: core statement on fexecve, O_EXEC, and O_SEARCH



On Wed, 5 Dec 2012 20:42:32 +0000
David Holland <dholland-tech%netbsd.org@localhost> wrote:

> That may be, but it's still true of file descriptors. Traditionally
> they're capabilities, and I really don't like the idea of rearranging
> that arbitrarily and inconsistently.
> 
> I think to do this correctly, exec and search on file handles needs to
> be handled the same as read and write: you must open with the
> corresponding O_ flag, and that then gives you a capability that
> remains valid until closed (or revoke(2)'d).

Ah yes! Modelling this in terms of capabilities is what I think has
been missing from this discussion. Or rather, nobody (myself included)
seems to have picked up on your previous mention. Of course, possessing
a capability, and possessing the capability to grant that capability[1]
are two different things. Is it really a good idea that any process
that can execute a file should automatically be able to allow another
process to do so? Conversely, there's not much point in being able to
pass the capability to another process if it needs to already have
execute permission.

> Because passing capabilities around is potentially dangerous, if we're
> going to add new capabilities we need to either be certain that no
> restrictions are needed, or add a mechanism to restrict capability
> passing. Since we clearly aren't certain (if anything, we're certain
> that restrictions are needed), someone needs to come up with a
> mechanism.

Are you saying what I just said, or something else? I think it's a good
idea to know how this thing can be abused before devising a mechanism
for restriction. It's ok to say “we're not certain” but taking a guess
risks restricting the wrong thing and leaving a hole wide open. I have
a fond memory of rooting[2] a friend's (Linux) box using rmt, which his
distribution had installed suid root. All his carefully set permissions
on devices were rendered pointless by this one oversight.

> There is a good bit of prior art we can take from in existing or
> historical capability systems, so designing a suitable mechanism and
> interface will probably take a bit of reading but shouldn't be very
> hard. Just remember that the process root directory is also a form of
> capability, and it shouldn't be that hard to figure out how to make
> everything interact.
> 
> This does mean we aren't going to be POSIX-compliant on O_EXEC and
> O_SEARCH (are there any other O_ flags involved?) but I think it's
> become clear that this is inevitable. When we're done we can decide if
> O_EXEC and O_SEARCH and the corresponding other bits should disappear
> or not when _POSIX_SOURCE and friends are defined to request strict
> POSIX.

There appears to be consensus on deviating from the spec. But it seems
clear to me that non-compliant behaviour shouldn't be enabled if strict
compliance is requested. Principle of least surprise: not implemented
is a hard failure mode and easy to handle; not compliant can lead to an
apparent success and a debugging nightmare.

> We also need to decide if the process root dir and process current dir
> are equivalent to file handles and are thus capabilities (meaning
> search permission does not need to be checked again at use time) or
> not. This could go either way and I don't currently have an opinion.

My instinct is to say that consistency is key, and therefore
considering all of these attributes as capabilities is the way to go.
However, this could change the behaviour of some code. One can imagine
a process A which has the ability to request that process B (with
different credentials) make permission changes on its behalf. What if A
asks to be denied search permission to its own cwd? Of course, this is
a contrived example. Perhaps it's not a problem.

> We're also going to need a way to encode capabilities such that they
> can be passed down from syscall code into vfs and filesystem code.
> When the only path requiring alternate forms of security check was
> truncate, it was ok to deal with it on an ad hoc basis; but now there
> are a lot of places that need to check either permissions or a
> capability, and I really don't want to be doing it in anything other
> than a systematic manner, especially in namei.

The obvious answer is to pass around a reference rather than the cap
itself. All operations on caps then are handled by functions/macros
that set/extract values in the global table as required - no code ever
touches them without going through the abstraction. I say global
because I'm thinking of the case where caps are passed between
processes. But there are other ways to solve that problem. Either way,
file descriptors are reduced to being a local alias to the relevant
capability. There may even be a cunning way to accelerate that lookup.


Julian

[1] I hate English. I'm talking about “able to do” vs “able to permit”.
[2] Like many insomniacs, I get naughtier as the night goes on.

-- 
3072D/F3A66B3A Julian Yon (2012 General Use) <pgp.2012%jry.me@localhost>

Attachment: signature.asc
Description: PGP signature



Home | Main Index | Thread Index | Old Index