microblaze: page.h: Remove get_user_page and free_user_page
[safe/jmp/linux-2.6] / kernel / cred.c
index 24dd2f5..62af181 100644 (file)
@@ -10,6 +10,7 @@
  */
 #include <linux/module.h>
 #include <linux/cred.h>
+#include <linux/slab.h>
 #include <linux/sched.h>
 #include <linux/key.h>
 #include <linux/keyctl.h>
@@ -147,7 +148,8 @@ static void put_cred_rcu(struct rcu_head *rcu)
        key_put(cred->thread_keyring);
        key_put(cred->request_key_auth);
        release_tgcred(cred);
-       put_group_info(cred->group_info);
+       if (cred->group_info)
+               put_group_info(cred->group_info);
        free_uid(cred->user);
        kmem_cache_free(cred_jar, cred);
 }
@@ -199,6 +201,49 @@ void exit_creds(struct task_struct *tsk)
        validate_creds(cred);
        alter_cred_subscribers(cred, -1);
        put_cred(cred);
+
+       cred = (struct cred *) tsk->replacement_session_keyring;
+       if (cred) {
+               tsk->replacement_session_keyring = NULL;
+               validate_creds(cred);
+               put_cred(cred);
+       }
+}
+
+/*
+ * Allocate blank credentials, such that the credentials can be filled in at a
+ * later date without risk of ENOMEM.
+ */
+struct cred *cred_alloc_blank(void)
+{
+       struct cred *new;
+
+       new = kmem_cache_zalloc(cred_jar, GFP_KERNEL);
+       if (!new)
+               return NULL;
+
+#ifdef CONFIG_KEYS
+       new->tgcred = kzalloc(sizeof(*new->tgcred), GFP_KERNEL);
+       if (!new->tgcred) {
+               kmem_cache_free(cred_jar, new);
+               return NULL;
+       }
+       atomic_set(&new->tgcred->usage, 1);
+#endif
+
+       atomic_set(&new->usage, 1);
+
+       if (security_cred_alloc_blank(new, GFP_KERNEL) < 0)
+               goto error;
+
+#ifdef CONFIG_DEBUG_CREDENTIALS
+       new->magic = CRED_MAGIC;
+#endif
+       return new;
+
+error:
+       abort_creds(new);
+       return NULL;
 }
 
 /**
@@ -320,7 +365,7 @@ struct cred *prepare_usermodehelper_creds(void)
 
        new = kmem_cache_alloc(cred_jar, GFP_ATOMIC);
        if (!new)
-               return NULL;
+               goto free_tgcred;
 
        kdebug("prepare_usermodehelper_creds() alloc %p", new);
 
@@ -354,6 +399,12 @@ struct cred *prepare_usermodehelper_creds(void)
 error:
        put_cred(new);
        return NULL;
+
+free_tgcred:
+#ifdef CONFIG_KEYS
+       kfree(tgcred);
+#endif
+       return NULL;
 }
 
 /*
@@ -738,6 +789,23 @@ EXPORT_SYMBOL(set_create_files_as);
 
 #ifdef CONFIG_DEBUG_CREDENTIALS
 
+bool creds_are_invalid(const struct cred *cred)
+{
+       if (cred->magic != CRED_MAGIC)
+               return true;
+#ifdef CONFIG_SECURITY_SELINUX
+       if (selinux_is_enabled()) {
+               if ((unsigned long) cred->security < PAGE_SIZE)
+                       return true;
+               if ((*(u32 *)cred->security & 0xffffff00) ==
+                   (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))
+                       return true;
+       }
+#endif
+       return false;
+}
+EXPORT_SYMBOL(creds_are_invalid);
+
 /*
  * dump invalid credentials
  */