From: "Serge E. Hallyn" <serue@us.ibm.com>
To: Oren Laadan <orenl@cs.columbia.edu>
Cc: Linux Containers <containers@lists.osdl.org>,
Alexey Dobriyan <adobriyan@gmail.com>,
Andrew Morgan <morgan@kernel.org>,
David Howells <dhowells@redhat.com>,
linux-security-module@vger.kernel.org
Subject: [PATCH 3/9] cr: break out new_user_ns()
Date: Fri, 29 May 2009 17:33:01 -0500 [thread overview]
Message-ID: <20090529223301.GC14602@us.ibm.com> (raw)
In-Reply-To: <20090529223229.GA14536@us.ibm.com>
Break out the core function which checks privilege and (if
allowed) creates a new user namespace, with the passed-in
creating user_struct. Note that a user_namespace, unlike
other namespace pointers, is not stored in the nsproxy.
Rather it is purely a property of user_structs.
This will let us keep the task restore code simpler.
Signed-off-by: Serge E. Hallyn <serue@us.ibm.com>
---
include/linux/user_namespace.h | 8 ++++++
kernel/user_namespace.c | 53 ++++++++++++++++++++++++++++------------
2 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h
index cc4f453..a2b82d5 100644
--- a/include/linux/user_namespace.h
+++ b/include/linux/user_namespace.h
@@ -20,6 +20,8 @@ extern struct user_namespace init_user_ns;
#ifdef CONFIG_USER_NS
+struct user_namespace *new_user_ns(struct user_struct *creator,
+ struct user_struct **newroot);
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
{
if (ns)
@@ -38,6 +40,12 @@ static inline void put_user_ns(struct user_namespace *ns)
#else
+static inline struct user_namespace *new_user_ns(struct user_struct *creator,
+ struct user_struct **newroot)
+{
+ return -EINVAL;
+}
+
static inline struct user_namespace *get_user_ns(struct user_namespace *ns)
{
return &init_user_ns;
diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index 076c7c8..e624b0f 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -11,15 +11,8 @@
#include <linux/user_namespace.h>
#include <linux/cred.h>
-/*
- * Create a new user namespace, deriving the creator from the user in the
- * passed credentials, and replacing that user with the new root user for the
- * new namespace.
- *
- * This is called by copy_creds(), which will finish setting the target task's
- * credentials.
- */
-int create_user_ns(struct cred *new)
+static struct user_namespace *_new_user_ns(struct user_struct *creator,
+ struct user_struct **newroot)
{
struct user_namespace *ns;
struct user_struct *root_user;
@@ -27,7 +20,7 @@ int create_user_ns(struct cred *new)
ns = kmalloc(sizeof(struct user_namespace), GFP_KERNEL);
if (!ns)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
kref_init(&ns->kref);
@@ -38,12 +31,43 @@ int create_user_ns(struct cred *new)
root_user = alloc_uid(ns, 0);
if (!root_user) {
kfree(ns);
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
}
/* set the new root user in the credentials under preparation */
- ns->creator = new->user;
- new->user = root_user;
+ ns->creator = creator;
+
+ /* alloc_uid() incremented the userns refcount. Just set it to 1 */
+ kref_set(&ns->kref, 1);
+
+ *newroot = root_user;
+ return ns;
+}
+
+struct user_namespace *new_user_ns(struct user_struct *creator,
+ struct user_struct **newroot)
+{
+ if (!capable(CAP_SYS_ADMIN))
+ return ERR_PTR(-EPERM);
+ return _new_user_ns(creator, newroot);
+}
+
+/*
+ * Create a new user namespace, deriving the creator from the user in the
+ * passed credentials, and replacing that user with the new root user for the
+ * new namespace.
+ *
+ * This is called by copy_creds(), which will finish setting the target task's
+ * credentials.
+ */
+int create_user_ns(struct cred *new)
+{
+ struct user_namespace *ns;
+
+ ns = new_user_ns(new->user, &new->user);
+ if (IS_ERR(ns))
+ return PTR_ERR(ns);
+
new->uid = new->euid = new->suid = new->fsuid = 0;
new->gid = new->egid = new->sgid = new->fsgid = 0;
put_group_info(new->group_info);
@@ -54,9 +78,6 @@ int create_user_ns(struct cred *new)
#endif
/* tgcred will be cleared in our caller bc CLONE_THREAD won't be set */
- /* alloc_uid() incremented the userns refcount. Just set it to 1 */
- kref_set(&ns->kref, 1);
-
return 0;
}
--
1.6.1
next prev parent reply other threads:[~2009-05-29 22:33 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-05-29 22:32 [PATCH 0/9] credentials c/r: Introduction Serge E. Hallyn
2009-05-29 22:32 ` [PATCH 1/9] cred: #include init.h in cred.h Serge E. Hallyn
2009-05-29 22:32 ` [PATCH 2/9] groups: move code to kernel/groups.c Serge E. Hallyn
2009-05-29 22:33 ` Serge E. Hallyn [this message]
2009-05-29 22:33 ` [PATCH 4/9] cr: split core function out of some set*{u,g}id functions Serge E. Hallyn
2009-05-29 22:33 ` [PATCH 5/9] cr: capabilities: define checkpoint and restore fns Serge E. Hallyn
2009-05-31 20:26 ` Andrew G. Morgan
2009-05-31 20:56 ` Alexey Dobriyan
2009-06-01 1:38 ` Serge E. Hallyn
2009-06-01 2:18 ` Andrew G. Morgan
2009-06-01 13:35 ` Serge E. Hallyn
2009-06-01 15:46 ` Andrew G. Morgan
2009-06-01 22:18 ` Serge E. Hallyn
2009-06-02 13:49 ` Andrew G. Morgan
2009-06-02 14:23 ` Serge E. Hallyn
2009-06-02 15:26 ` Oren Laadan
2009-06-02 15:49 ` Andrew G. Morgan
2009-06-02 17:15 ` Serge E. Hallyn
2009-06-03 0:05 ` Oren Laadan
[not found] ` <4A25BE4F.6000603-eQaUEPhvms7ENvBUuze7eA@public.gmane.org>
2009-06-03 15:03 ` Andrew G. Morgan
2009-06-03 16:45 ` Serge E. Hallyn
2009-06-04 14:13 ` Andrew G. Morgan
2009-06-05 19:41 ` Serge E. Hallyn
2009-06-06 15:02 ` Andrew G. Morgan
2009-06-15 9:58 ` Alexey Dobriyan
2009-06-01 15:49 ` Serge E. Hallyn
2009-06-01 16:34 ` Oren Laadan
2009-05-29 22:33 ` [PATCH 6/9] cr: checkpoint and restore task credentials Serge E. Hallyn
[not found] ` <20090529223229.GA14536-r/Jw6+rmf7HQT0dZR+AlfA@public.gmane.org>
2009-05-29 22:33 ` [PATCH 7/9] cr: restore file->f_cred Serge E. Hallyn
2009-05-29 22:33 ` [PATCH 8/9] user namespaces: debug refcounts Serge E. Hallyn
2009-05-31 18:51 ` Alexey Dobriyan
2009-06-01 19:02 ` Serge E. Hallyn
2009-05-29 22:34 ` [PATCH 9/9] cr: ipc: reset kern_ipc_perms Serge E. Hallyn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090529223301.GC14602@us.ibm.com \
--to=serue@us.ibm.com \
--cc=adobriyan@gmail.com \
--cc=containers@lists.osdl.org \
--cc=dhowells@redhat.com \
--cc=linux-security-module@vger.kernel.org \
--cc=morgan@kernel.org \
--cc=orenl@cs.columbia.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.