]> Pileus Git - ~andy/linux/blobdiff - ipc/namespace.c
audit: stop pushing loginid, uid, sessionid as arguments
[~andy/linux] / ipc / namespace.c
index f362298c5ce465e3585dfd2cbfdd528e29e4790d..7c1fa451b0b0d75ae5265fea8fbe1193cb865223 100644 (file)
@@ -16,7 +16,7 @@
 
 #include "util.h"
 
-static struct ipc_namespace *create_ipc_ns(struct task_struct *tsk,
+static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
                                           struct ipc_namespace *old_ns)
 {
        struct ipc_namespace *ns;
@@ -26,9 +26,16 @@ static struct ipc_namespace *create_ipc_ns(struct task_struct *tsk,
        if (ns == NULL)
                return ERR_PTR(-ENOMEM);
 
+       err = proc_alloc_inum(&ns->proc_inum);
+       if (err) {
+               kfree(ns);
+               return ERR_PTR(err);
+       }
+
        atomic_set(&ns->count, 1);
        err = mq_init_ns(ns);
        if (err) {
+               proc_free_inum(ns->proc_inum);
                kfree(ns);
                return ERR_PTR(err);
        }
@@ -46,19 +53,17 @@ static struct ipc_namespace *create_ipc_ns(struct task_struct *tsk,
        ipcns_notify(IPCNS_CREATED);
        register_ipcns_notifier(ns);
 
-       ns->user_ns = get_user_ns(task_cred_xxx(tsk, user_ns));
+       ns->user_ns = get_user_ns(user_ns);
 
        return ns;
 }
 
 struct ipc_namespace *copy_ipcs(unsigned long flags,
-                               struct task_struct *tsk)
+       struct user_namespace *user_ns, struct ipc_namespace *ns)
 {
-       struct ipc_namespace *ns = tsk->nsproxy->ipc_ns;
-
        if (!(flags & CLONE_NEWIPC))
                return get_ipc_ns(ns);
-       return create_ipc_ns(tsk, ns);
+       return create_ipc_ns(user_ns, ns);
 }
 
 /*
@@ -113,6 +118,7 @@ static void free_ipc_ns(struct ipc_namespace *ns)
         */
        ipcns_notify(IPCNS_REMOVED);
        put_user_ns(ns->user_ns);
+       proc_free_inum(ns->proc_inum);
        kfree(ns);
 }
 
@@ -161,8 +167,13 @@ static void ipcns_put(void *ns)
        return put_ipc_ns(ns);
 }
 
-static int ipcns_install(struct nsproxy *nsproxy, void *ns)
+static int ipcns_install(struct nsproxy *nsproxy, void *new)
 {
+       struct ipc_namespace *ns = new;
+       if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
+           !nsown_capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
        /* Ditch state from the old ipc namespace */
        exit_sem(current);
        put_ipc_ns(nsproxy->ipc_ns);
@@ -170,10 +181,18 @@ static int ipcns_install(struct nsproxy *nsproxy, void *ns)
        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,
 };