Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6
[sfrench/cifs-2.6.git] / security / keys / process_keys.c
index 4d9825f9962cb027e5f610380177d2722d60aca0..c886a2bb792ae034950ec71aa20af5fd1d4c17ee 100644 (file)
@@ -26,8 +26,8 @@ static DEFINE_MUTEX(key_session_mutex);
 /* the root user's tracking struct */
 struct key_user root_key_user = {
        .usage          = ATOMIC_INIT(3),
-       .consq          = LIST_HEAD_INIT(root_key_user.consq),
-       .lock           = SPIN_LOCK_UNLOCKED,
+       .cons_lock      = __MUTEX_INITIALIZER(root_key_user.cons_lock),
+       .lock           = __SPIN_LOCK_UNLOCKED(root_key_user.lock),
        .nkeys          = ATOMIC_INIT(2),
        .nikeys         = ATOMIC_INIT(2),
        .uid            = 0,
@@ -77,7 +77,8 @@ int alloc_uid_keyring(struct user_struct *user,
        /* concoct a default session keyring */
        sprintf(buf, "_uid_ses.%u", user->uid);
 
-       session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0, NULL);
+       session_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx,
+                                       KEY_ALLOC_IN_QUOTA, NULL);
        if (IS_ERR(session_keyring)) {
                ret = PTR_ERR(session_keyring);
                goto error;
@@ -87,8 +88,8 @@ int alloc_uid_keyring(struct user_struct *user,
         * keyring */
        sprintf(buf, "_uid.%u", user->uid);
 
-       uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx, 0,
-                                   session_keyring);
+       uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, ctx,
+                                   KEY_ALLOC_IN_QUOTA, session_keyring);
        if (IS_ERR(uid_keyring)) {
                key_put(session_keyring);
                ret = PTR_ERR(uid_keyring);
@@ -144,7 +145,8 @@ int install_thread_keyring(struct task_struct *tsk)
 
        sprintf(buf, "_tid.%u", tsk->pid);
 
-       keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
+       keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk,
+                               KEY_ALLOC_QUOTA_OVERRUN, NULL);
        if (IS_ERR(keyring)) {
                ret = PTR_ERR(keyring);
                goto error;
@@ -178,7 +180,8 @@ int install_process_keyring(struct task_struct *tsk)
        if (!tsk->signal->process_keyring) {
                sprintf(buf, "_pid.%u", tsk->tgid);
 
-               keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
+               keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk,
+                                       KEY_ALLOC_QUOTA_OVERRUN, NULL);
                if (IS_ERR(keyring)) {
                        ret = PTR_ERR(keyring);
                        goto error;
@@ -209,6 +212,7 @@ error:
 static int install_session_keyring(struct task_struct *tsk,
                                   struct key *keyring)
 {
+       unsigned long flags;
        struct key *old;
        char buf[20];
 
@@ -218,7 +222,12 @@ static int install_session_keyring(struct task_struct *tsk,
        if (!keyring) {
                sprintf(buf, "_ses.%u", tsk->tgid);
 
-               keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk, 1, NULL);
+               flags = KEY_ALLOC_QUOTA_OVERRUN;
+               if (tsk->signal->session_keyring)
+                       flags = KEY_ALLOC_IN_QUOTA;
+
+               keyring = keyring_alloc(buf, tsk->uid, tsk->gid, tsk,
+                                       flags, NULL);
                if (IS_ERR(keyring))
                        return PTR_ERR(keyring);
        }
@@ -651,7 +660,7 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
 
                key = key_lookup(id);
                if (IS_ERR(key)) {
-                       key_ref = ERR_PTR(PTR_ERR(key));
+                       key_ref = ERR_CAST(key);
                        goto error;
                }
 
@@ -670,8 +679,18 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
                break;
        }
 
-       /* check the status */
-       if (perm) {
+       if (!partial) {
+               ret = wait_for_key_construction(key, true);
+               switch (ret) {
+               case -ERESTARTSYS:
+                       goto invalid_key;
+               default:
+                       if (perm)
+                               goto invalid_key;
+               case 0:
+                       break;
+               }
+       } else if (perm) {
                ret = key_validate(key);
                if (ret < 0)
                        goto invalid_key;
@@ -728,7 +747,8 @@ long join_session_keyring(const char *name)
        keyring = find_keyring_by_name(name, 0);
        if (PTR_ERR(keyring) == -ENOKEY) {
                /* not found - try and create a new one */
-               keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk, 0, NULL);
+               keyring = keyring_alloc(name, tsk->uid, tsk->gid, tsk,
+                                       KEY_ALLOC_IN_QUOTA, NULL);
                if (IS_ERR(keyring)) {
                        ret = PTR_ERR(keyring);
                        goto error2;