CRED: Make execve() take advantage of copy-on-write credentials
[deliverable/linux.git] / kernel / cred.c
index cb6b5eda978df8d6a30866f1adbaae7382c4b8a8..e6fcdd67b2ec94bde93d4a9c4c4e3e37bbef3238 100644 (file)
@@ -68,7 +68,7 @@ static void release_tgcred_rcu(struct rcu_head *rcu)
 /*
  * Release a set of thread group credentials.
  */
-void release_tgcred(struct cred *cred)
+static void release_tgcred(struct cred *cred)
 {
 #ifdef CONFIG_KEYS
        struct thread_group_cred *tgcred = cred->tgcred;
@@ -163,6 +163,50 @@ error:
 }
 EXPORT_SYMBOL(prepare_creds);
 
+/*
+ * Prepare credentials for current to perform an execve()
+ * - The caller must hold current->cred_exec_mutex
+ */
+struct cred *prepare_exec_creds(void)
+{
+       struct thread_group_cred *tgcred = NULL;
+       struct cred *new;
+
+#ifdef CONFIG_KEYS
+       tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL);
+       if (!tgcred)
+               return NULL;
+#endif
+
+       new = prepare_creds();
+       if (!new) {
+               kfree(tgcred);
+               return new;
+       }
+
+#ifdef CONFIG_KEYS
+       /* newly exec'd tasks don't get a thread keyring */
+       key_put(new->thread_keyring);
+       new->thread_keyring = NULL;
+
+       /* create a new per-thread-group creds for all this set of threads to
+        * share */
+       memcpy(tgcred, new->tgcred, sizeof(struct thread_group_cred));
+
+       atomic_set(&tgcred->usage, 1);
+       spin_lock_init(&tgcred->lock);
+
+       /* inherit the session keyring; new process keyring */
+       key_get(tgcred->session_keyring);
+       tgcred->process_keyring = NULL;
+
+       release_tgcred(new);
+       new->tgcred = tgcred;
+#endif
+
+       return new;
+}
+
 /*
  * prepare new credentials for the usermode helper dispatcher
  */
This page took 0.02595 seconds and 5 git commands to generate.