Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
[pandora-kernel.git] / kernel / cred.c
index 13697ca..3a03918 100644 (file)
@@ -274,6 +274,7 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
        struct thread_group_cred *tgcred;
 #endif
        struct cred *new;
+       int ret;
 
        mutex_init(&p->cred_exec_mutex);
 
@@ -293,6 +294,12 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
        if (!new)
                return -ENOMEM;
 
+       if (clone_flags & CLONE_NEWUSER) {
+               ret = create_user_ns(new);
+               if (ret < 0)
+                       goto error_put;
+       }
+
 #ifdef CONFIG_KEYS
        /* new threads get their own thread keyrings if their parent already
         * had one */
@@ -309,8 +316,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
        if (!(clone_flags & CLONE_THREAD)) {
                tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL);
                if (!tgcred) {
-                       put_cred(new);
-                       return -ENOMEM;
+                       ret = -ENOMEM;
+                       goto error_put;
                }
                atomic_set(&tgcred->usage, 1);
                spin_lock_init(&tgcred->lock);
@@ -325,6 +332,10 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
        atomic_inc(&new->user->processes);
        p->cred = p->real_cred = get_cred(new);
        return 0;
+
+error_put:
+       put_cred(new);
+       return ret;
 }
 
 /**
@@ -361,7 +372,8 @@ int commit_creds(struct cred *new)
            old->fsuid != new->fsuid ||
            old->fsgid != new->fsgid ||
            !cap_issubset(new->cap_permitted, old->cap_permitted)) {
-               set_dumpable(task->mm, suid_dumpable);
+               if (task->mm)
+                       set_dumpable(task->mm, suid_dumpable);
                task->pdeath_signal = 0;
                smp_wmb();
        }
@@ -495,6 +507,7 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
        else
                old = get_cred(&init_cred);
 
+       *new = *old;
        get_uid(new->user);
        get_group_info(new->group_info);
 
@@ -518,6 +531,7 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
 
 error:
        put_cred(new);
+       put_cred(old);
        return NULL;
 }
 EXPORT_SYMBOL(prepare_kernel_cred);