From 435d5f4bb2ccba3b791d9ef61d2590e30b8e806e Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 31 Oct 2014 22:56:04 -0400 Subject: common object embedded into various struct ....ns for now - just move corresponding ->proc_inum instances over there Acked-by: "Eric W. Biederman" Signed-off-by: Al Viro --- kernel/pid.c | 2 +- kernel/pid_namespace.c | 6 +++--- kernel/user.c | 2 +- kernel/user_namespace.c | 6 +++--- kernel/utsname.c | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'kernel') diff --git a/kernel/pid.c b/kernel/pid.c index 9b9a26698144..3650698cf1dc 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -79,7 +79,7 @@ struct pid_namespace init_pid_ns = { .level = 0, .child_reaper = &init_task, .user_ns = &init_user_ns, - .proc_inum = PROC_PID_INIT_INO, + .ns.inum = PROC_PID_INIT_INO, }; EXPORT_SYMBOL_GPL(init_pid_ns); diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index db95d8eb761b..99e27e5bf906 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -105,7 +105,7 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns if (ns->pid_cachep == NULL) goto out_free_map; - err = proc_alloc_inum(&ns->proc_inum); + err = proc_alloc_inum(&ns->ns.inum); if (err) goto out_free_map; @@ -142,7 +142,7 @@ static void destroy_pid_namespace(struct pid_namespace *ns) { int i; - proc_free_inum(ns->proc_inum); + proc_free_inum(ns->ns.inum); for (i = 0; i < PIDMAP_ENTRIES; i++) kfree(ns->pidmap[i].page); put_user_ns(ns->user_ns); @@ -365,7 +365,7 @@ static int pidns_install(struct nsproxy *nsproxy, void *ns) static unsigned int pidns_inum(void *ns) { struct pid_namespace *pid_ns = ns; - return pid_ns->proc_inum; + return pid_ns->ns.inum; } const struct proc_ns_operations pidns_operations = { diff --git a/kernel/user.c b/kernel/user.c index 4efa39350e44..a7ca84bad8e6 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -50,7 +50,7 @@ struct user_namespace init_user_ns = { .count = ATOMIC_INIT(3), .owner = GLOBAL_ROOT_UID, .group = GLOBAL_ROOT_GID, - .proc_inum = PROC_USER_INIT_INO, + .ns.inum = PROC_USER_INIT_INO, #ifdef CONFIG_PERSISTENT_KEYRINGS .persistent_keyring_register_sem = __RWSEM_INITIALIZER(init_user_ns.persistent_keyring_register_sem), diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index aa312b0dc3ec..fde584082673 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -86,7 +86,7 @@ int create_user_ns(struct cred *new) if (!ns) return -ENOMEM; - ret = proc_alloc_inum(&ns->proc_inum); + ret = proc_alloc_inum(&ns->ns.inum); if (ret) { kmem_cache_free(user_ns_cachep, ns); return ret; @@ -136,7 +136,7 @@ void free_user_ns(struct user_namespace *ns) #ifdef CONFIG_PERSISTENT_KEYRINGS key_put(ns->persistent_keyring_register); #endif - proc_free_inum(ns->proc_inum); + proc_free_inum(ns->ns.inum); kmem_cache_free(user_ns_cachep, ns); ns = parent; } while (atomic_dec_and_test(&parent->count)); @@ -891,7 +891,7 @@ static int userns_install(struct nsproxy *nsproxy, void *ns) static unsigned int userns_inum(void *ns) { struct user_namespace *user_ns = ns; - return user_ns->proc_inum; + return user_ns->ns.inum; } const struct proc_ns_operations userns_operations = { diff --git a/kernel/utsname.c b/kernel/utsname.c index 883aaaa7de8a..b1cd00b828f2 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -42,7 +42,7 @@ static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns, if (!ns) return ERR_PTR(-ENOMEM); - err = proc_alloc_inum(&ns->proc_inum); + err = proc_alloc_inum(&ns->ns.inum); if (err) { kfree(ns); return ERR_PTR(err); @@ -84,7 +84,7 @@ void free_uts_ns(struct kref *kref) ns = container_of(kref, struct uts_namespace, kref); put_user_ns(ns->user_ns); - proc_free_inum(ns->proc_inum); + proc_free_inum(ns->ns.inum); kfree(ns); } @@ -127,7 +127,7 @@ static unsigned int utsns_inum(void *vp) { struct uts_namespace *ns = vp; - return ns->proc_inum; + return ns->ns.inum; } const struct proc_ns_operations utsns_operations = { -- cgit v1.2.3 From 3c0411846118a578de3a979faf2da3ab5fb81179 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 1 Nov 2014 00:25:30 -0400 Subject: switch the rest of proc_ns_operations to working with &...->ns Signed-off-by: Al Viro --- kernel/pid_namespace.c | 14 +++++++++----- kernel/user_namespace.c | 14 +++++++++----- kernel/utsname.c | 15 +++++++++------ 3 files changed, 27 insertions(+), 16 deletions(-) (limited to 'kernel') diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 99e27e5bf906..dd961ad86fbd 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -313,6 +313,11 @@ int reboot_pid_ns(struct pid_namespace *pid_ns, int cmd) return 0; } +static inline struct pid_namespace *to_pid_ns(struct ns_common *ns) +{ + return container_of(ns, struct pid_namespace, ns); +} + static void *pidns_get(struct task_struct *task) { struct pid_namespace *ns; @@ -323,18 +328,18 @@ static void *pidns_get(struct task_struct *task) get_pid_ns(ns); rcu_read_unlock(); - return ns; + return ns ? &ns->ns : NULL; } static void pidns_put(void *ns) { - put_pid_ns(ns); + put_pid_ns(to_pid_ns(ns)); } static int pidns_install(struct nsproxy *nsproxy, void *ns) { struct pid_namespace *active = task_active_pid_ns(current); - struct pid_namespace *ancestor, *new = ns; + struct pid_namespace *ancestor, *new = to_pid_ns(ns); if (!ns_capable(new->user_ns, CAP_SYS_ADMIN) || !ns_capable(current_user_ns(), CAP_SYS_ADMIN)) @@ -364,8 +369,7 @@ static int pidns_install(struct nsproxy *nsproxy, void *ns) static unsigned int pidns_inum(void *ns) { - struct pid_namespace *pid_ns = ns; - return pid_ns->ns.inum; + return ((struct ns_common *)ns)->inum; } const struct proc_ns_operations pidns_operations = { diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index fde584082673..1ab2209228ff 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -841,6 +841,11 @@ static bool new_idmap_permitted(const struct file *file, return false; } +static inline struct user_namespace *to_user_ns(struct ns_common *ns) +{ + return container_of(ns, struct user_namespace, ns); +} + static void *userns_get(struct task_struct *task) { struct user_namespace *user_ns; @@ -849,17 +854,17 @@ static void *userns_get(struct task_struct *task) user_ns = get_user_ns(__task_cred(task)->user_ns); rcu_read_unlock(); - return user_ns; + return user_ns ? &user_ns->ns : NULL; } static void userns_put(void *ns) { - put_user_ns(ns); + put_user_ns(to_user_ns(ns)); } static int userns_install(struct nsproxy *nsproxy, void *ns) { - struct user_namespace *user_ns = ns; + struct user_namespace *user_ns = to_user_ns(ns); struct cred *cred; /* Don't allow gaining capabilities by reentering @@ -890,8 +895,7 @@ static int userns_install(struct nsproxy *nsproxy, void *ns) static unsigned int userns_inum(void *ns) { - struct user_namespace *user_ns = ns; - return user_ns->ns.inum; + return ((struct ns_common *)ns)->inum; } const struct proc_ns_operations userns_operations = { diff --git a/kernel/utsname.c b/kernel/utsname.c index b1cd00b828f2..1917f74be8ec 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -88,6 +88,11 @@ void free_uts_ns(struct kref *kref) kfree(ns); } +static inline struct uts_namespace *to_uts_ns(struct ns_common *ns) +{ + return container_of(ns, struct uts_namespace, ns); +} + static void *utsns_get(struct task_struct *task) { struct uts_namespace *ns = NULL; @@ -101,17 +106,17 @@ static void *utsns_get(struct task_struct *task) } task_unlock(task); - return ns; + return ns ? &ns->ns : NULL; } static void utsns_put(void *ns) { - put_uts_ns(ns); + put_uts_ns(to_uts_ns(ns)); } static int utsns_install(struct nsproxy *nsproxy, void *new) { - struct uts_namespace *ns = new; + struct uts_namespace *ns = to_uts_ns(new); if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) || !ns_capable(current_user_ns(), CAP_SYS_ADMIN)) @@ -125,9 +130,7 @@ static int utsns_install(struct nsproxy *nsproxy, void *new) static unsigned int utsns_inum(void *vp) { - struct uts_namespace *ns = vp; - - return ns->ns.inum; + return ((struct ns_common *)vp)->inum; } const struct proc_ns_operations utsns_operations = { -- cgit v1.2.3 From 64964528b24ea390824f0e5ce9d34b8d39b28cde Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 1 Nov 2014 00:37:32 -0400 Subject: make proc_ns_operations work with struct ns_common * instead of void * We can do that now. And kill ->inum(), while we are at it - all instances are identical. Signed-off-by: Al Viro --- kernel/pid_namespace.c | 12 +++--------- kernel/user_namespace.c | 12 +++--------- kernel/utsname.c | 12 +++--------- 3 files changed, 9 insertions(+), 27 deletions(-) (limited to 'kernel') diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index dd961ad86fbd..79aabce49a85 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -318,7 +318,7 @@ static inline struct pid_namespace *to_pid_ns(struct ns_common *ns) return container_of(ns, struct pid_namespace, ns); } -static void *pidns_get(struct task_struct *task) +static struct ns_common *pidns_get(struct task_struct *task) { struct pid_namespace *ns; @@ -331,12 +331,12 @@ static void *pidns_get(struct task_struct *task) return ns ? &ns->ns : NULL; } -static void pidns_put(void *ns) +static void pidns_put(struct ns_common *ns) { put_pid_ns(to_pid_ns(ns)); } -static int pidns_install(struct nsproxy *nsproxy, void *ns) +static int pidns_install(struct nsproxy *nsproxy, struct ns_common *ns) { struct pid_namespace *active = task_active_pid_ns(current); struct pid_namespace *ancestor, *new = to_pid_ns(ns); @@ -367,18 +367,12 @@ static int pidns_install(struct nsproxy *nsproxy, void *ns) return 0; } -static unsigned int pidns_inum(void *ns) -{ - return ((struct ns_common *)ns)->inum; -} - const struct proc_ns_operations pidns_operations = { .name = "pid", .type = CLONE_NEWPID, .get = pidns_get, .put = pidns_put, .install = pidns_install, - .inum = pidns_inum, }; static __init int pid_namespaces_init(void) diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 1ab2209228ff..29cd5ccfc37a 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -846,7 +846,7 @@ static inline struct user_namespace *to_user_ns(struct ns_common *ns) return container_of(ns, struct user_namespace, ns); } -static void *userns_get(struct task_struct *task) +static struct ns_common *userns_get(struct task_struct *task) { struct user_namespace *user_ns; @@ -857,12 +857,12 @@ static void *userns_get(struct task_struct *task) return user_ns ? &user_ns->ns : NULL; } -static void userns_put(void *ns) +static void userns_put(struct ns_common *ns) { put_user_ns(to_user_ns(ns)); } -static int userns_install(struct nsproxy *nsproxy, void *ns) +static int userns_install(struct nsproxy *nsproxy, struct ns_common *ns) { struct user_namespace *user_ns = to_user_ns(ns); struct cred *cred; @@ -893,18 +893,12 @@ static int userns_install(struct nsproxy *nsproxy, void *ns) return commit_creds(cred); } -static unsigned int userns_inum(void *ns) -{ - return ((struct ns_common *)ns)->inum; -} - const struct proc_ns_operations userns_operations = { .name = "user", .type = CLONE_NEWUSER, .get = userns_get, .put = userns_put, .install = userns_install, - .inum = userns_inum, }; static __init int user_namespaces_init(void) diff --git a/kernel/utsname.c b/kernel/utsname.c index 1917f74be8ec..20697befe466 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -93,7 +93,7 @@ static inline struct uts_namespace *to_uts_ns(struct ns_common *ns) return container_of(ns, struct uts_namespace, ns); } -static void *utsns_get(struct task_struct *task) +static struct ns_common *utsns_get(struct task_struct *task) { struct uts_namespace *ns = NULL; struct nsproxy *nsproxy; @@ -109,12 +109,12 @@ static void *utsns_get(struct task_struct *task) return ns ? &ns->ns : NULL; } -static void utsns_put(void *ns) +static void utsns_put(struct ns_common *ns) { put_uts_ns(to_uts_ns(ns)); } -static int utsns_install(struct nsproxy *nsproxy, void *new) +static int utsns_install(struct nsproxy *nsproxy, struct ns_common *new) { struct uts_namespace *ns = to_uts_ns(new); @@ -128,16 +128,10 @@ static int utsns_install(struct nsproxy *nsproxy, void *new) return 0; } -static unsigned int utsns_inum(void *vp) -{ - return ((struct ns_common *)vp)->inum; -} - const struct proc_ns_operations utsns_operations = { .name = "uts", .type = CLONE_NEWUTS, .get = utsns_get, .put = utsns_put, .install = utsns_install, - .inum = utsns_inum, }; -- cgit v1.2.3 From 6344c433a452b1a05d03a61a6a85d89f793bb7b8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 1 Nov 2014 00:45:45 -0400 Subject: new helpers: ns_alloc_inum/ns_free_inum take struct ns_common *, for now simply wrappers around proc_{alloc,free}_inum() Signed-off-by: Al Viro --- kernel/pid_namespace.c | 4 ++-- kernel/user_namespace.c | 4 ++-- kernel/utsname.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'kernel') diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 79aabce49a85..5aa9158a84d5 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -105,7 +105,7 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns if (ns->pid_cachep == NULL) goto out_free_map; - err = proc_alloc_inum(&ns->ns.inum); + err = ns_alloc_inum(&ns->ns); if (err) goto out_free_map; @@ -142,7 +142,7 @@ static void destroy_pid_namespace(struct pid_namespace *ns) { int i; - proc_free_inum(ns->ns.inum); + ns_free_inum(&ns->ns); for (i = 0; i < PIDMAP_ENTRIES; i++) kfree(ns->pidmap[i].page); put_user_ns(ns->user_ns); diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 29cd5ccfc37a..6bf8177768e5 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -86,7 +86,7 @@ int create_user_ns(struct cred *new) if (!ns) return -ENOMEM; - ret = proc_alloc_inum(&ns->ns.inum); + ret = ns_alloc_inum(&ns->ns); if (ret) { kmem_cache_free(user_ns_cachep, ns); return ret; @@ -136,7 +136,7 @@ void free_user_ns(struct user_namespace *ns) #ifdef CONFIG_PERSISTENT_KEYRINGS key_put(ns->persistent_keyring_register); #endif - proc_free_inum(ns->ns.inum); + ns_free_inum(&ns->ns); kmem_cache_free(user_ns_cachep, ns); ns = parent; } while (atomic_dec_and_test(&parent->count)); diff --git a/kernel/utsname.c b/kernel/utsname.c index 20697befe466..c2a2b321d88a 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -42,7 +42,7 @@ static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns, if (!ns) return ERR_PTR(-ENOMEM); - err = proc_alloc_inum(&ns->ns.inum); + err = ns_alloc_inum(&ns->ns); if (err) { kfree(ns); return ERR_PTR(err); @@ -84,7 +84,7 @@ void free_uts_ns(struct kref *kref) ns = container_of(kref, struct uts_namespace, kref); put_user_ns(ns->user_ns); - proc_free_inum(ns->ns.inum); + ns_free_inum(&ns->ns); kfree(ns); } -- cgit v1.2.3 From 33c429405a2c8d9e42afb9fee88a63cfb2de1e98 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 1 Nov 2014 02:32:53 -0400 Subject: copy address of proc_ns_ops into ns_common Signed-off-by: Al Viro --- kernel/nsproxy.c | 8 ++++---- kernel/pid.c | 3 +++ kernel/pid_namespace.c | 1 + kernel/user.c | 3 +++ kernel/user_namespace.c | 1 + kernel/utsname.c | 2 ++ 6 files changed, 14 insertions(+), 4 deletions(-) (limited to 'kernel') diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index ef42d0ab3115..87c37221cb7f 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c @@ -220,11 +220,11 @@ void exit_task_namespaces(struct task_struct *p) SYSCALL_DEFINE2(setns, int, fd, int, nstype) { - const struct proc_ns_operations *ops; struct task_struct *tsk = current; struct nsproxy *new_nsproxy; struct proc_ns *ei; struct file *file; + struct ns_common *ns; int err; file = proc_ns_fget(fd); @@ -233,8 +233,8 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype) err = -EINVAL; ei = get_proc_ns(file_inode(file)); - ops = ei->ns_ops; - if (nstype && (ops->type != nstype)) + ns = ei->ns; + if (nstype && (ns->ops->type != nstype)) goto out; new_nsproxy = create_new_namespaces(0, tsk, current_user_ns(), tsk->fs); @@ -243,7 +243,7 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype) goto out; } - err = ops->install(new_nsproxy, ei->ns); + err = ns->ops->install(new_nsproxy, ns); if (err) { free_nsproxy(new_nsproxy); goto out; diff --git a/kernel/pid.c b/kernel/pid.c index 3650698cf1dc..c17a993a4d2a 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -80,6 +80,9 @@ struct pid_namespace init_pid_ns = { .child_reaper = &init_task, .user_ns = &init_user_ns, .ns.inum = PROC_PID_INIT_INO, +#ifdef CONFIG_PID_NS + .ns.ops = &pidns_operations, +#endif }; EXPORT_SYMBOL_GPL(init_pid_ns); diff --git a/kernel/pid_namespace.c b/kernel/pid_namespace.c index 5aa9158a84d5..e1bafe3b47bb 100644 --- a/kernel/pid_namespace.c +++ b/kernel/pid_namespace.c @@ -108,6 +108,7 @@ static struct pid_namespace *create_pid_namespace(struct user_namespace *user_ns err = ns_alloc_inum(&ns->ns); if (err) goto out_free_map; + ns->ns.ops = &pidns_operations; kref_init(&ns->kref); ns->level = level; diff --git a/kernel/user.c b/kernel/user.c index a7ca84bad8e6..69b800aebf13 100644 --- a/kernel/user.c +++ b/kernel/user.c @@ -51,6 +51,9 @@ struct user_namespace init_user_ns = { .owner = GLOBAL_ROOT_UID, .group = GLOBAL_ROOT_GID, .ns.inum = PROC_USER_INIT_INO, +#ifdef CONFIG_USER_NS + .ns.ops = &userns_operations, +#endif #ifdef CONFIG_PERSISTENT_KEYRINGS .persistent_keyring_register_sem = __RWSEM_INITIALIZER(init_user_ns.persistent_keyring_register_sem), diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c index 6bf8177768e5..1491ad00388f 100644 --- a/kernel/user_namespace.c +++ b/kernel/user_namespace.c @@ -91,6 +91,7 @@ int create_user_ns(struct cred *new) kmem_cache_free(user_ns_cachep, ns); return ret; } + ns->ns.ops = &userns_operations; atomic_set(&ns->count, 1); /* Leave the new->user_ns reference with the new user namespace. */ diff --git a/kernel/utsname.c b/kernel/utsname.c index c2a2b321d88a..831ea7108232 100644 --- a/kernel/utsname.c +++ b/kernel/utsname.c @@ -48,6 +48,8 @@ static struct uts_namespace *clone_uts_ns(struct user_namespace *user_ns, return ERR_PTR(err); } + ns->ns.ops = &utsns_operations; + down_read(&uts_sem); memcpy(&ns->name, &old_ns->name, sizeof(ns->name)); ns->user_ns = get_user_ns(user_ns); -- cgit v1.2.3 From f77c80142e1afe6d5c16975ca5d7d1fc324b16f9 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sat, 1 Nov 2014 03:13:17 -0400 Subject: bury struct proc_ns in fs/proc a) make get_proc_ns() return a pointer to struct ns_common b) mirror ns_ops in dentry->d_fsdata of ns dentries, so that is_mnt_ns_file() could get away with fewer dereferences. That way struct proc_ns becomes invisible outside of fs/proc/*.c Signed-off-by: Al Viro --- kernel/nsproxy.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'kernel') diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c index 87c37221cb7f..49746c81ad8d 100644 --- a/kernel/nsproxy.c +++ b/kernel/nsproxy.c @@ -222,7 +222,6 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype) { struct task_struct *tsk = current; struct nsproxy *new_nsproxy; - struct proc_ns *ei; struct file *file; struct ns_common *ns; int err; @@ -232,8 +231,7 @@ SYSCALL_DEFINE2(setns, int, fd, int, nstype) return PTR_ERR(file); err = -EINVAL; - ei = get_proc_ns(file_inode(file)); - ns = ei->ns; + ns = get_proc_ns(file_inode(file)); if (nstype && (ns->ops->type != nstype)) goto out; -- cgit v1.2.3