On Mon, Mar 31, 2014 at 1:14 PM, Trond Myklebust
<trond.mykleb...@primarydata.com> wrote:
>
> On Mar 31, 2014, at 15:26, Andy Lutomirski <l...@amacapital.net> wrote:
>
>> On Mon, Mar 31, 2014 at 11:06 AM, Trond Myklebust
>> <trond.mykleb...@primarydata.com> wrote:
>>>
>>> On Mar 31, 2014, at 7:51, Jeff Layton <jlay...@redhat.com> wrote:
>>>
>>>> On Sun, 30 Mar 2014 09:03:29 -0400
>>>> "Theodore Ts'o" <ty...@mit.edu> wrote:
>>>>
>>>>> On Thu, Mar 27, 2014 at 07:08:02AM -0700, Jeff Layton wrote:
>>>>>> I had some time to think about this last night...
>>>>>>
>>>>>> While using a fd to pass around credentials is convenient, the danger
>>>>>> is that it's pretty opaque. You have a fd that you know has creds
>>>>>> attached to it, but it's hard to be certain what is going to change.
>>>>>
>>>>> I don't think that's a particularly tough problem.  In general, the fd
>>>>> isn't something that you would want to pass around, and so the process
>>>>> which generated it will know exactly what it contained.
>>>>>
>>>>
>>>> I think there's a bit more of a use-case for passing around such an fd
>>>> via socket...
>>>>
>>>> Part of the problem is that the traditional uid/gid switching glibc
>>>> wrappers are per-process. If we're proposing doing something like:
>>>>
>>>> seteuid()
>>>> setegid()
>>>> setgroups()
>>>> fd = open()
>>>> (...and then revert the creds using same syscalls)
>>>>
>>>> ...during the time that you're doing all of that, you can't really
>>>> allow any thread in the process to be doing something that requires
>>>> _other_ creds until you've completed the above.
>>>
>>> Umm... open() isn't the only operation that you want to be able to do with 
>>> an assumed user identity. You want mknod(), mkdir(), link(), unlink(), ... 
>>> Pretty much any interaction with the underlying filesystem needs to use the 
>>> right identity.
>>>
>>>> So, I could envision a program like ganesha firing up a separate
>>>> process to handle the credential switching and fd creation and then
>>>> handing those back to the main process via a unix domain socket.
>>>
>>> How about using the keyrings interface to atomically cache and retrieve 
>>> these user identities? We already have support for different types of keys 
>>> that store/retrieve different types of structured information. How is this 
>>> so different?
>>
>> This sounds considerably more complicated than just using fds.  What's
>> the advantage?
>
> The advantage is that it's considerably _less_ complicated because it uses 
> interfaces that were designed to carry security related information, and to 
> share them across threads.
>
>> I guess using keys for local fs credentials fits in with using keys to
>> access things like AFS, but I'm still not sure I see why this helps
>> here.
>
> All you want to do is atomically store and retrieve a user identity (in 
> practice a credential) and share it between members of a thread. As I said, 
> that kind of storage/retrieval of structured data is what keyrings do. As far 
> as I know, there are already LSM interfaces in place (see 
> security_key_alloc/permission/free), and the generic keyring/keyctl interface 
> exists with appropriate process sharing/inheritance rules via the kernel 
> keyring interface.
>
> So basically, the recipe is:
>
> - You set up a kernel key type that takes a reference to the current process 
> credential on instantiation (no upcalls, etc needed). Ganesha can then use 
> standard libkeyutils methods to create the key and store it in its user, 
> process or thread keyring.
> - You add a new keyctl (KEYCTL_APPLY?) that enables any thread/process that 
> has access to the key, via the keyring in which it is stored, to apply the 
> stored process credential to itself (and perhaps cache it's old credential in 
> a new key?).

I can see pros and cons of using keys instead of fds:

Pros:
 - You can change may_ptrace to check that you can legally ptrace any
creds in the keyring.  (It's debatable how useful this is.)
 - You could plausibly stick subsidiary uids into a user keyring and
use them for uid_map, removing the need for newuidmap.

Cons:
 - You can't send them via SCM_RIGHTS.  I still think that the ability
to do that is extremely useful.

Neutral: What happens if the filesystem you're trying to share
requires keys?  I don't think that credfd or credkeys can really do
this.  I suppose that if the keys live in the user keyring
corresponding to the user being impersonated, everything just works
regardless of how this is implemented.

Cue brain explosion: thread_keyring lives inside struct cred.  I
suspect that any sane implementation of credential switching will need
to change that.  Sigh.


Anyway, the actual parts that seem like they need solving one way or
another are:

 - The keyring pointers in struct cred are a problem.  (Solved with
credkeys, but only if credkeys can only live on the thread keyring.
Also, there will be a problem with circular references.)

 - may_ptrace and all its users (e.g. procfs).  "Solved" by
real_creds, but no one has really defined the semantics of real_creds,
since it's not currently available to userspace.

--Andy
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to