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/