diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2011-06-18 07:00:10 -0700 |
---|---|---|
committer | Eric W. Biederman <ebiederm@aristanetworks.com> | 2011-08-08 13:51:05 -0500 |
commit | b619360f585cdcff4d4b89f5aae8c2e66b264d97 (patch) | |
tree | 03338373816cd36b81b64c51ba13e87a7dc2741f | |
parent | 08352c310547a6af760b91f94db0900405a766a1 (diff) | |
download | linux-namespace-control-devel-b619360f585cdcff4d4b89f5aae8c2e66b264d97.tar.gz |
ns proc: Add support for the user namespace
Add the basic namespace file support, but do not
add support for setns.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
-rw-r--r-- | fs/proc/namespaces.c | 3 | ||||
-rw-r--r-- | include/linux/proc_fs.h | 2 | ||||
-rw-r--r-- | include/linux/user_namespace.h | 1 | ||||
-rw-r--r-- | kernel/user.c | 2 | ||||
-rw-r--r-- | kernel/user_namespace.c | 40 |
5 files changed, 48 insertions, 0 deletions
diff --git a/fs/proc/namespaces.c b/fs/proc/namespaces.c index 65bfeec5fcb3f6..f500ed94e58ed0 100644 --- a/fs/proc/namespaces.c +++ b/fs/proc/namespaces.c @@ -26,6 +26,9 @@ static const struct proc_ns_operations *ns_entries[] = { &ipcns_operations, #endif &mntns_operations, +#ifdef CONFIG_USER_NS + &userns_operations, +#endif }; static const struct file_operations ns_file_operations = { diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 9ca36ea3878cc3..86d4b399bc3e39 100644 --- a/include/linux/proc_fs.h +++ b/include/linux/proc_fs.h @@ -31,6 +31,7 @@ enum { PROC_ROOT_INO = 1, PROC_IPC_INIT_INO = 0xEFFFFFFFU, PROC_UTS_INIT_INO = 0xEFFFFFFEU, + PROC_USER_INIT_INO = 0xEFFFFFFDU, }; @@ -272,6 +273,7 @@ extern const struct proc_ns_operations netns_operations; extern const struct proc_ns_operations utsns_operations; extern const struct proc_ns_operations ipcns_operations; extern const struct proc_ns_operations mntns_operations; +extern const struct proc_ns_operations userns_operations; union proc_op { int (*proc_get_link)(struct inode *, struct path *); diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index faf467944bafc0..5ecc9888c22bb8 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -14,6 +14,7 @@ struct user_namespace { struct hlist_head uidhash_table[UIDHASH_SZ]; struct user_struct *creator; struct work_struct destroyer; + unsigned int proc_inum; }; extern struct user_namespace init_user_ns; diff --git a/kernel/user.c b/kernel/user.c index 9e03e9c1df8d47..867fc657c4587b 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -16,6 +16,7 @@ #include <linux/interrupt.h> #include <linux/module.h> #include <linux/user_namespace.h> +#include <linux/proc_fs.h> /* * userns count is 1 for root user, 1 for init_uts_ns, @@ -26,6 +27,7 @@ struct user_namespace init_user_ns = { .refcount = ATOMIC_INIT(3), }, .creator = &root_user, + .proc_inum = PROC_USER_INIT_INO, }; EXPORT_SYMBOL_GPL(init_user_ns); diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 9da289c34f22f1..3c2e8f8d35bc52 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -11,6 +11,7 @@ #include <linux/user_namespace.h> #include <linux/highuid.h> #include <linux/cred.h> +#include <linux/proc_fs.h> static struct kmem_cache *user_ns_cachep __read_mostly; @@ -27,11 +28,18 @@ int create_user_ns(struct cred *new) struct user_namespace *ns; struct user_struct *root_user; int n; + int ret; ns = kmem_cache_alloc(user_ns_cachep, GFP_KERNEL); if (!ns) return -ENOMEM; + ret = proc_alloc_inum(&ns->proc_inum); + if (ret) { + kmem_cache_free(user_ns_cachep, ns); + return ret; + } + kref_init(&ns->kref); for (n = 0; n < UIDHASH_SZ; ++n) @@ -40,6 +48,7 @@ int create_user_ns(struct cred *new) /* Alloc new root user. */ root_user = alloc_uid(ns, 0); if (!root_user) { + proc_free_inum(ns->proc_inum); kmem_cache_free(user_ns_cachep, ns); return -ENOMEM; } @@ -73,6 +82,7 @@ static void free_user_ns_work(struct work_struct *work) struct user_namespace *ns = container_of(work, struct user_namespace, destroyer); free_uid(ns->creator); + proc_free_inum(ns->proc_inum); kmem_cache_free(user_ns_cachep, ns); } @@ -135,3 +145,33 @@ static __init int user_namespaces_init(void) return 0; } module_init(user_namespaces_init); + +static void *userns_get(struct task_struct *task) +{ + return get_user_ns(task_cred_xxx(task, user)->user_ns); +} + +static void userns_put(void *ns) +{ + put_user_ns(ns); +} + +static int userns_install(struct nsproxy *nsproxy, void *ns) +{ + return -EINVAL; +} + +static unsigned int userns_inum(void *ns) +{ + struct user_namespace *user_ns = ns; + return user_ns->proc_inum; +} + +const struct proc_ns_operations userns_operations = { + .name = "user", + .type = CLONE_NEWNS, + .get = userns_get, + .put = userns_put, + .install = userns_install, + .inum = userns_inum, +}; |