OpenVZ Forum - RDF feed
type: channel
items: design of user namespaces
items: Re: design of user namespaces

design of user namespaces
type: item
description: I got to thinking about the user namespace again today and I wanted to summarize my thoughts. First and foremost I want a design that solves the suid problem, and I think I have. In particular if we can let an unprivileged user run a process in a different user namespace, and become a user with 0 == uid == gid and have all capabilities except CAP_SYS_RAWIO and they still can not do anything security wise they could not before. We have a very useful design. My thinking is as follows. - All user visible security credentials uid, gid, selinux filesystem lables, etc will be relative to a user namespace. This makes security easier, and it the only thing that makes sense in the concept of separate administrative domain. - Each struct user will live in exactly one user namespace. - Each user namespace will hold the struct user of the user who created the user namespace. - capable() will be extended to take a user namespace parameter. So the question capable asks is does the current process have the capability with respect to the current user namespace. This makes security namespaces loosely hierarchical. And the rule would be that if you could do something to the files and directories and other objects owned by the creator of the namespace you can do it to objects owned by users in the user namespace. Going the other direction from child to parent user namespaces, users in user namespace no matter what capabilities they have will have no permissions except those given to every process. - Each user namespace will have a bounding set of capabilities that suid executables and the initial process get. Basically something so fundamentally machine specific capabilities like CAP_SYS_RAWIO can never be set inside of a user namespace unless the creator of the user namespace had those capabilities. - The initial user in a user namespace will be uid 0 and have all capabilities, non machine specific cpabilities CAP_NET_ADMIN, CAP_SYS_ADMIN, CAP_SYS_CHROOT etc. Since those capabilities…
creator: ebiederm
date: 2008-06-20T02:01:08-00:00

Re: design of user namespaces
type: item
description: Quoting Eric W. Biederman (ebiederm@xmission.com): > > I got to thinking about the user namespace again > today and I wanted to summarize my thoughts. > > First and foremost I want a design that solves the suid problem, > and I think I have. > > In particular if we can let an unprivileged user run a process > in a different user namespace, and become a user with 0 == uid == gid > and have all capabilities except CAP_SYS_RAWIO and they still can not > do anything security wise they could not before. We have a very useful design. > > My thinking is as follows. > - All user visible security credentials uid, gid, selinux filesystem lables, > etc will be relative to a user namespace. > > This makes security easier, and it the only thing that makes > sense in the concept of separate administrative domain. > > - Each struct user will live in exactly one user namespace. > > - Each user namespace will hold the struct user of the user who > created the user namespace. > > - capable() will be extended to take a user namespace parameter. So > the question capable asks is does the current process have the > capability with respect to the current user namespace. > > This makes security namespaces loosely hierarchical. And the rule > would be that if you could do something to the files and directories > and other objects owned by the creator of the namespace you can do > it to objects owned by users in the user namespace. > > Going the other direction from child to parent user namespaces, > users in user namespace no matter what capabilities they have will > have no permissions except those given to every process. > > - Each user namespace will have a bounding set of capabilities that > suid executables and the initial process get. Basically something > so fundamentally machine specific capabilities like CAP_SYS_RAWIO > can never be set inside of a user namespace unless the creator of > the user namespace had those capabilities. > > - The initial user in a user namespace will be u…
creator: serue
date: 2008-06-20T14:05:10-00:00

Re: design of user namespaces
type: item
description: "Serge E. Hallyn" <serue@us.ibm.com> writes: > > Hi Eric, > > glad you're giving this some thought. Did you ever read over the > approach which I outlined in May (see > http://forum.openvz.org/index.php?t=msg&goto=30223&)? We agree on many > points. I think we basically solve the suid problem the same way. I hadn't read that post although I saw a part of it in your paper. Solving that problem so unprivileged users can use a user namespace seems to be the key to making namespaces more widely usable, and recursive. Plus I really like the idea of a super nobody user. > But I've moved away from a uid-to-uid mapping. Instead, > I expand on the relation you also describe: the user who creates a user > namespace owns the user namespace and introduce a persistant > namespace ID. I think there are management issues with a persistent namespace ID. In particular: Is this user allowed to use this ID? That is the reason I want to avoid having a generic persistent namespace ID. Implementing a common library and then modifying the filesystems to use it on a case by case basis sounds much more maintainable. Then picking the wrong direction does not bind us for all time and eternity. > I understand that you may reflexively balk at introducing a new global > persistant ID when we're focusing on turning everything into a > namespace, but I think that would be a misguided reflex (like the > ioctl->netlinke one of a few years ago). In particular, in your > approach the identifier is the combination of the uid-to-uid mapping and > the uids stored on the original filesystem. Not at all. I thought I had mentioned the xattr thing as one of the possibilities. I forgot the proper term so I probably said acls. The practical problem is that you then have to rev your quota support. To also support the xattr separation. In addition not every filesystem supports xattrs. Although the common ones do. > I do think the particular form of the ID I suggest will be unsuitable > and we'll want something m…
creator: ebiederm
date: 2008-06-20T19:03:21-00:00

Re: design of user namespaces
type: item
description: Quoting Eric W. Biederman (ebiederm@xmission.com): > "Serge E. Hallyn" <serue@us.ibm.com> writes: > > > > Hi Eric, > > > > glad you're giving this some thought. Did you ever read over the > > approach which I outlined in May (see > > http://forum.openvz.org/index.php?t=msg&goto=30223&)? We agree on many > > points. I think we basically solve the suid problem the same way. > > I hadn't read that post although I saw a part of it in your paper. > Solving that problem so unprivileged users can use a user namespace > seems to be the key to making namespaces more widely usable, and > recursive. Plus I really like the idea of a super nobody user. > > > But I've moved away from a uid-to-uid mapping. Instead, > > I expand on the relation you also describe: the user who creates a user > > namespace owns the user namespace and introduce a persistant > > namespace ID. > > I think there are management issues with a persistent namespace ID. There are. But one key point is that the namespace ids are not cryptographic keys. They don't need to be globally unique, or even 100% unique on one system (though that gets too subtle). I was wanting to keep them tiny - or at least variably sized - so they could be stored with each inode. > In particular: Is this user allowed to use this ID? One way to address that is actually by having a system-wide tool with CAP_SET_USERNS=fp which enforces a userid-to-unsid mapping. The host sysadmin creates a table, say, 500:0 may use unsid 10-15. 500:0 (let's call him hallyn) doesn't have CAP_SET_USERNS permissions himself, but can run /bin/set_unsid, which runs with CAP_SET_USERNS and ensures that hallyn uses only unsids 10-15. It's not ideal. I'd rather have some sort of fancy collision-proof global persistant id system, but again I think it's important that if 500:0 creates userns 1 and 400:1 creates userns 2, and 0:2 creates a file, that the file be persistantly marked as belonging to (500:0,400:1,0:2), distinct from another file created by (500:0,40…
creator: serue
date: 2008-06-20T20:55:08-00:00

Re: design of user namespaces
type: item
description: Quoting Serge E. Hallyn (serue@us.ibm.com): > > Just skimming through your patch I don't expect we will need the list > > of children, and not having should reduct our locking burden. > > Hmm, that's true. I can't see a reason for that. Thanks! BTW here is the new, slightly smaller patch: >From d17fbd87d97f64a0e879a7efbe5e1835fc573eae Mon Sep 17 00:00:00 2001 From: Serge Hallyn <serge@us.ibm.com> Date: Thu, 19 Jun 2008 20:18:17 -0500 Subject: [PATCH 1/1] user namespaces: introduce user_struct->user_namespace relationship When a task does clone(CLONE_NEWNS), the task's user is the 'creator' of the new user_namespace, and the user_namespace is tacked onto a list of those created by this user. When we create or put a user in a namespace, we also do so for all creator users up the creator chain. Changelog: Jun 20: Eric Biederman pointed out the sibling/child_user_ns list is unnecessary! Signed-off-by: Serge Hallyn <serge@us.ibm.com> --- include/linux/sched.h | 1 + include/linux/user_namespace.h | 1 + kernel/user.c | 66 +++++++++++++++++++++++++++++++++++++++- kernel/user_namespace.c | 15 +++------ 4 files changed, 72 insertions(+), 11 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 799bbdd..da1bcc6 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -604,6 +604,7 @@ struct user_struct { /* Hash table maintenance information */ struct hlist_node uidhash_node; uid_t uid; + struct user_namespace *user_namespace; #ifdef CONFIG_USER_SCHED struct task_group *tg; diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index b5f41d4..f9477c3 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -13,6 +13,7 @@ struct user_namespace { struct kref kref; struct hlist_head uidhash_table[UIDHASH_SZ]; struct user_struct *root_user; + struct user_struct *creator; }; extern struct user_namespace init_user_ns; diff --git a/kernel/user.c b/kernel/user.c index 865ecf5..e583be4 100644 --- a/kernel…
creator: serue
date: 2008-06-20T21:47:46-00:00

Re: design of user namespaces
type: item
description: "Serge E. Hallyn" <serue@us.ibm.com> writes: > There are. But one key point is that the namespace ids are not > cryptographic keys. They don't need to be globally unique, or even 100% > unique on one system (though that gets too subtle). > > I was wanting to keep them tiny - or at least variably sized - so they > could be stored with each inode. Sure. I think they make a lot of sense. idmapd uses domain names for this purpose. At the moment I just don't think the are necessary. Like veth isn't necessary for network namespaces. Ultimately we will use these identifiers all of the time but it doesn't mean the generic code has to deal with them. >> In particular: Is this user allowed to use this ID? > > One way to address that is actually by having a system-wide tool with > CAP_SET_USERNS=fp which enforces a userid-to-unsid mapping. The host > sysadmin creates a table, say, 500:0 may use unsid 10-15. 500:0 (let's > call him hallyn) doesn't have CAP_SET_USERNS permissions himself, but > can run /bin/set_unsid, which runs with CAP_SET_USERNS and ensures that > hallyn uses only unsids 10-15. > > It's not ideal. I'd rather have some sort of fancy collision-proof > global persistant id system, but again I think it's important that if > 500:0 creates userns 1 and 400:1 creates userns 2, and 0:2 creates a > file, that the file be persistantly marked as belonging to > (500:0,400:1,0:2), distinct from another file created by > (500:0,400:1,1000:2). Which means these things have to be stored > per-inode, meaning they can't be too large. So my suggestion was something like this: mount -o nativemount,uidns=1 / Then the filesystem performs magic to ask if the owner of user namespace is allowed to use uidns 1. That magic would consult a config file like: [domains] local1.mydomain 1 local2.mydomain 2 local3.mydomain 3 [users] bob local1.mydomain bob local3.mydomain nancy local2.mydomain Or something like that. Reporting which users are allowed to use which userid namespaces, and the m…
creator: ebiederm
date: 2008-06-20T23:00:12-00:00

Re: design of user namespaces
type: item
description: "Serge E. Hallyn" <serue@us.ibm.com> writes: > Quoting Serge E. Hallyn (serue@us.ibm.com): >> > Just skimming through your patch I don't expect we will need the list >> > of children, and not having should reduct our locking burden. >> >> Hmm, that's true. I can't see a reason for that. Thanks! > > BTW here is the new, slightly smaller patch: > >>From d17fbd87d97f64a0e879a7efbe5e1835fc573eae Mon Sep 17 00:00:00 2001 > From: Serge Hallyn <serge@us.ibm.com> > Date: Thu, 19 Jun 2008 20:18:17 -0500 > Subject: [PATCH 1/1] user namespaces: introduce user_struct->user_namespace > relationship > > When a task does clone(CLONE_NEWNS), the task's user is the 'creator' of the > new user_namespace, and the user_namespace is tacked onto a list of those > created by this user. > > When we create or put a user in a namespace, we also do so for all creator > users up the creator chain. > > Changelog: > Jun 20: Eric Biederman pointed out the sibling/child_user_ns > list is unnecessary! > > Signed-off-by: Serge Hallyn <serge@us.ibm.com> > --- > include/linux/sched.h | 1 + > include/linux/user_namespace.h | 1 + > kernel/user.c | 66 +++++++++++++++++++++++++++++++++++++++- > kernel/user_namespace.c | 15 +++------ > 4 files changed, 72 insertions(+), 11 deletions(-) > > diff --git a/include/linux/sched.h b/include/linux/sched.h > index 799bbdd..da1bcc6 100644 > --- a/include/linux/sched.h > +++ b/include/linux/sched.h > @@ -604,6 +604,7 @@ struct user_struct { > /* Hash table maintenance information */ > struct hlist_node uidhash_node; > uid_t uid; > + struct user_namespace *user_namespace; > > #ifdef CONFIG_USER_SCHED > struct task_group *tg; > diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h > index b5f41d4..f9477c3 100644 > --- a/include/linux/user_namespace.h > +++ b/include/linux/user_namespace.h > @@ -13,6 +13,7 @@ struct user_namespace { > struct kref kref; > struct hlist_head uidhash_table[UIDHASH_SZ]; > struct user_struct *root_user; > + struct user_…
creator: ebiederm
date: 2008-06-20T23:07:45-00:00

Re: design of user namespaces
type: item
description: Quoting Eric W. Biederman (ebiederm@xmission.com): > "Serge E. Hallyn" <serue@us.ibm.com> writes: > > > Quoting Serge E. Hallyn (serue@us.ibm.com): > >> > Just skimming through your patch I don't expect we will need the list > >> > of children, and not having should reduct our locking burden. > >> > >> Hmm, that's true. I can't see a reason for that. Thanks! > > > > BTW here is the new, slightly smaller patch: > > > >>From d17fbd87d97f64a0e879a7efbe5e1835fc573eae Mon Sep 17 00:00:00 2001 > > From: Serge Hallyn <serge@us.ibm.com> > > Date: Thu, 19 Jun 2008 20:18:17 -0500 > > Subject: [PATCH 1/1] user namespaces: introduce user_struct->user_namespace > > relationship > > > > When a task does clone(CLONE_NEWNS), the task's user is the 'creator' of the > > new user_namespace, and the user_namespace is tacked onto a list of those > > created by this user. > > > > When we create or put a user in a namespace, we also do so for all creator > > users up the creator chain. > > > > Changelog: > > Jun 20: Eric Biederman pointed out the sibling/child_user_ns > > list is unnecessary! > > > > Signed-off-by: Serge Hallyn <serge@us.ibm.com> > > --- > > include/linux/sched.h | 1 + > > include/linux/user_namespace.h | 1 + > > kernel/user.c | 66 +++++++++++++++++++++++++++++++++++++++- > > kernel/user_namespace.c | 15 +++------ > > 4 files changed, 72 insertions(+), 11 deletions(-) > > > > diff --git a/include/linux/sched.h b/include/linux/sched.h > > index 799bbdd..da1bcc6 100644 > > --- a/include/linux/sched.h > > +++ b/include/linux/sched.h > > @@ -604,6 +604,7 @@ struct user_struct { > > /* Hash table maintenance information */ > > struct hlist_node uidhash_node; > > uid_t uid; > > + struct user_namespace *user_namespace; > > > > #ifdef CONFIG_USER_SCHED > > struct task_group *tg; > > diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h > > index b5f41d4..f9477c3 100644 > > --- a/include/linux/user_namespace.h > > +++ b/include/linux/user_namespace.h > > @@ …
creator: serue
date: 2008-06-21T19:05:32-00:00

Re: design of user namespaces
type: item
description: Quoting Eric W. Biederman (ebiederm@xmission.com): > "Serge E. Hallyn" <serue@us.ibm.com> writes: > > > There are. But one key point is that the namespace ids are not > > cryptographic keys. They don't need to be globally unique, or even 100% > > unique on one system (though that gets too subtle). > > > > I was wanting to keep them tiny - or at least variably sized - so they > > could be stored with each inode. > > Sure. I think they make a lot of sense. idmapd uses domain names > for this purpose. At the moment I just don't think the are necessary. > Like veth isn't necessary for network namespaces. Ultimately we > will use these identifiers all of the time but it doesn't mean > the generic code has to deal with them. > > > >> In particular: Is this user allowed to use this ID? > > > > One way to address that is actually by having a system-wide tool with > > CAP_SET_USERNS=fp which enforces a userid-to-unsid mapping. The host > > sysadmin creates a table, say, 500:0 may use unsid 10-15. 500:0 (let's > > call him hallyn) doesn't have CAP_SET_USERNS permissions himself, but > > can run /bin/set_unsid, which runs with CAP_SET_USERNS and ensures that > > hallyn uses only unsids 10-15. > > > > It's not ideal. I'd rather have some sort of fancy collision-proof > > global persistant id system, but again I think it's important that if > > 500:0 creates userns 1 and 400:1 creates userns 2, and 0:2 creates a > > file, that the file be persistantly marked as belonging to > > (500:0,400:1,0:2), distinct from another file created by > > (500:0,400:1,1000:2). Which means these things have to be stored > > per-inode, meaning they can't be too large. > > So my suggestion was something like this: > mount -o nativemount,uidns=1 / > > Then the filesystem performs magic to ask if the owner of user namespace > is allowed to use uidns 1. That magic would consult a config file like: > > [domains] > local1.mydomain 1 > local2.mydomain 2 > local3.mydomain 3 > > [users] > bob local1.mydomai…
creator: serue
date: 2008-06-30T21:13:25-00:00

Re: design of user namespaces
type: item
description: "Serge E. Hallyn" <serue@us.ibm.com> writes: > Quoting Eric W. Biederman (ebiederm@xmission.com): >> >> The very important points are that it is a remount of an existing mount >> so that we don't have to worry about corrupted filesystem attacks, and >> that authentication is performed at mount time. > > Conceptually that (making corrupted fs attacks a non-issue) is > wonderful. Practically, I may be missing something: When you say > remount, it seems you must either mean a bind mount or a remount. If > remount, then that will want to change superblock flags. If the > child userns(+child mntns) does a real remount, then that will change > the flags for the parent ns as well, right? > > If instead we do a bind mount we don't have that problem, but then the > fs can't be the one doing the user namespace work. > > I'm probably missing something. Essentially I am creating a new mount operation that is a cousin of a remount. Unlike a real remount you can't change the super flags. Unlike a bind mount you get the fs involved, and you pass in a string of flags that the fs can interpret in a standard way. I expect the flags you pass in would be a subset of what is allowed in a normal remount. Which is why I was calling it nativemount. Although usernsmount may be better. Eric _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: ebiederm
date: 2008-07-01T07:35:33-00:00

Re: design of user namespaces
type: item
description: Quoting Eric W. Biederman (ebiederm@xmission.com): > "Serge E. Hallyn" <serue@us.ibm.com> writes: > > > Quoting Eric W. Biederman (ebiederm@xmission.com): > >> > >> The very important points are that it is a remount of an existing mount > >> so that we don't have to worry about corrupted filesystem attacks, and > >> that authentication is performed at mount time. > > > > Conceptually that (making corrupted fs attacks a non-issue) is > > wonderful. Practically, I may be missing something: When you say > > remount, it seems you must either mean a bind mount or a remount. If > > remount, then that will want to change superblock flags. If the > > child userns(+child mntns) does a real remount, then that will change > > the flags for the parent ns as well, right? > > > > If instead we do a bind mount we don't have that problem, but then the > > fs can't be the one doing the user namespace work. > > > > I'm probably missing something. > > Essentially I am creating a new mount operation that is a > cousin of a remount. > > Unlike a real remount you can't change the super flags. > Unlike a bind mount you get the fs involved, and you pass in a string of flags > that the fs can interpret in a standard way. > > I expect the flags you pass in would be a subset of what is allowed > in a normal remount. > > Which is why I was calling it nativemount. Although usernsmount > may be better. > > Eric Ah, ok. Now you haven't started any sort of coding for this yet, right? I'm hoping to get some time later this week to think about/play with this. -serge _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: serue
date: 2008-07-07T15:24:06-00:00

Re: design of user namespaces
type: item
description: "Serge E. Hallyn" <serue@us.ibm.com> writes: > Ah, ok. > > Now you haven't started any sort of coding for this yet, right? I'm > hoping to get some time later this week to think about/play with this. Not yet. I'm hoping to do something in the near future, as this seems to be a killer feature though. Eric _______________________________________________ Containers mailing list Containers@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/containers
creator: ebiederm
date: 2008-07-07T19:25:23-00:00