X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=ipc%2Fnamespace.c;h=068caf18d56509711e46b47b25a363254d681abe;hb=5d2060410cd1419db48767f55cf0bb65290c7c1d;hp=aba9a586c667cb272c26b6d67eedc5748422230d;hpb=f6e46ae658e4443e765f87702603deca167f2b57;p=firefly-linux-kernel-4.4.55.git diff --git a/ipc/namespace.c b/ipc/namespace.c index aba9a586c667..068caf18d565 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -26,16 +26,17 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, if (ns == NULL) return ERR_PTR(-ENOMEM); - err = proc_alloc_inum(&ns->proc_inum); + err = ns_alloc_inum(&ns->ns); if (err) { kfree(ns); return ERR_PTR(err); } + ns->ns.ops = &ipcns_operations; atomic_set(&ns->count, 1); err = mq_init_ns(ns); if (err) { - proc_free_inum(ns->proc_inum); + ns_free_inum(&ns->ns); kfree(ns); return ERR_PTR(err); } @@ -45,14 +46,6 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, msg_init_ns(ns); shm_init_ns(ns); - /* - * msgmni has already been computed for the new ipc ns. - * Thus, do the ipcns creation notification before registering that - * new ipcns in the chain. - */ - ipcns_notify(IPCNS_CREATED); - register_ipcns_notifier(ns); - ns->user_ns = get_user_ns(user_ns); return ns; @@ -99,27 +92,13 @@ void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids, static void free_ipc_ns(struct ipc_namespace *ns) { - /* - * Unregistering the hotplug notifier at the beginning guarantees - * that the ipc namespace won't be freed while we are inside the - * callback routine. Since the blocking_notifier_chain_XXX routines - * hold a rw lock on the notifier list, unregister_ipcns_notifier() - * won't take the rw lock before blocking_notifier_call_chain() has - * released the rd lock. - */ - unregister_ipcns_notifier(ns); sem_exit_ns(ns); msg_exit_ns(ns); shm_exit_ns(ns); atomic_dec(&nr_ipc_ns); - /* - * Do the ipcns removal notification after decrementing nr_ipc_ns in - * order to have a correct value when recomputing msgmni. - */ - ipcns_notify(IPCNS_REMOVED); put_user_ns(ns->user_ns); - proc_free_inum(ns->proc_inum); + ns_free_inum(&ns->ns); kfree(ns); } @@ -149,30 +128,35 @@ void put_ipc_ns(struct ipc_namespace *ns) } } -static void *ipcns_get(struct task_struct *task) +static inline struct ipc_namespace *to_ipc_ns(struct ns_common *ns) +{ + return container_of(ns, struct ipc_namespace, ns); +} + +static struct ns_common *ipcns_get(struct task_struct *task) { struct ipc_namespace *ns = NULL; struct nsproxy *nsproxy; - rcu_read_lock(); - nsproxy = task_nsproxy(task); + task_lock(task); + nsproxy = task->nsproxy; if (nsproxy) ns = get_ipc_ns(nsproxy->ipc_ns); - rcu_read_unlock(); + task_unlock(task); - return ns; + return ns ? &ns->ns : NULL; } -static void ipcns_put(void *ns) +static void ipcns_put(struct ns_common *ns) { - return put_ipc_ns(ns); + return put_ipc_ns(to_ipc_ns(ns)); } -static int ipcns_install(struct nsproxy *nsproxy, void *new) +static int ipcns_install(struct nsproxy *nsproxy, struct ns_common *new) { - struct ipc_namespace *ns = new; + struct ipc_namespace *ns = to_ipc_ns(new); if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) || - !nsown_capable(CAP_SYS_ADMIN)) + !ns_capable(current_user_ns(), CAP_SYS_ADMIN)) return -EPERM; /* Ditch state from the old ipc namespace */ @@ -182,18 +166,10 @@ static int ipcns_install(struct nsproxy *nsproxy, void *new) return 0; } -static unsigned int ipcns_inum(void *vp) -{ - struct ipc_namespace *ns = vp; - - return ns->proc_inum; -} - const struct proc_ns_operations ipcns_operations = { .name = "ipc", .type = CLONE_NEWIPC, .get = ipcns_get, .put = ipcns_put, .install = ipcns_install, - .inum = ipcns_inum, };