const char *desc,
                             uid_t uid, gid_t gid,
                             struct task_struct *ctx,
-                            key_perm_t perm, int not_in_quota);
+                            key_perm_t perm,
+                            unsigned long flags);
+
+
+#define KEY_ALLOC_IN_QUOTA     0x0000  /* add to quota, reject if would overrun */
+#define KEY_ALLOC_QUOTA_OVERRUN        0x0001  /* add to quota, permit even if overrun */
+#define KEY_ALLOC_NOT_IN_QUOTA 0x0002  /* not in quota */
+
 extern int key_payload_reserve(struct key *key, size_t datalen);
 extern int key_instantiate_and_link(struct key *key,
                                    const void *data,
                                      const char *description,
                                      const void *payload,
                                      size_t plen,
-                                     int not_in_quota);
+                                     unsigned long flags);
 
 extern int key_update(key_ref_t key,
                      const void *payload,
 
 extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
                                 struct task_struct *ctx,
-                                int not_in_quota,
+                                unsigned long flags,
                                 struct key *dest);
 
 extern int keyring_clear(struct key *keyring);
 
  *     Permit allocation of a key and assign security data. Note that key does
  *     not have a serial number assigned at this point.
  *     @key points to the key.
+ *     @flags is the allocation flags
  *     Return 0 if permission is granted, -ve error otherwise.
  * @key_free:
  *     Notification of destruction; free security data.
 
        /* key management security hooks */
 #ifdef CONFIG_KEYS
-       int (*key_alloc)(struct key *key, struct task_struct *tsk);
+       int (*key_alloc)(struct key *key, struct task_struct *tsk, unsigned long flags);
        void (*key_free)(struct key *key);
        int (*key_permission)(key_ref_t key_ref,
                              struct task_struct *context,
 #ifdef CONFIG_KEYS
 #ifdef CONFIG_SECURITY
 static inline int security_key_alloc(struct key *key,
-                                    struct task_struct *tsk)
+                                    struct task_struct *tsk,
+                                    unsigned long flags)
 {
-       return security_ops->key_alloc(key, tsk);
+       return security_ops->key_alloc(key, tsk, flags);
 }
 
 static inline void security_key_free(struct key *key)
 #else
 
 static inline int security_key_alloc(struct key *key,
-                                    struct task_struct *tsk)
+                                    struct task_struct *tsk,
+                                    unsigned long flags)
 {
        return 0;
 }
 
 }
 
 #ifdef CONFIG_KEYS
-static inline int dummy_key_alloc(struct key *key, struct task_struct *ctx)
+static inline int dummy_key_alloc(struct key *key, struct task_struct *ctx,
+                                 unsigned long flags)
 {
        return 0;
 }
 
 extern struct key *request_key_and_link(struct key_type *type,
                                        const char *description,
                                        const char *callout_info,
-                                       struct key *dest_keyring);
+                                       struct key *dest_keyring,
+                                       unsigned long flags);
 
 /*
  * request_key authorisation
 
  */
 struct key *key_alloc(struct key_type *type, const char *desc,
                      uid_t uid, gid_t gid, struct task_struct *ctx,
-                     key_perm_t perm, int not_in_quota)
+                     key_perm_t perm, unsigned long flags)
 {
        struct key_user *user = NULL;
        struct key *key;
 
        /* check that the user's quota permits allocation of another key and
         * its description */
-       if (!not_in_quota) {
+       if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
                spin_lock(&user->lock);
-               if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS ||
-                   user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES
-                   )
-                       goto no_quota;
+               if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) {
+                       if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS ||
+                           user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES
+                           )
+                               goto no_quota;
+               }
 
                user->qnkeys++;
                user->qnbytes += quotalen;
        key->payload.data = NULL;
        key->security = NULL;
 
-       if (!not_in_quota)
+       if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
                key->flags |= 1 << KEY_FLAG_IN_QUOTA;
 
        memset(&key->type_data, 0, sizeof(key->type_data));
 #endif
 
        /* let the security module know about the key */
-       ret = security_key_alloc(key, ctx);
+       ret = security_key_alloc(key, ctx, flags);
        if (ret < 0)
                goto security_error;
 
 security_error:
        kfree(key->description);
        kmem_cache_free(key_jar, key);
-       if (!not_in_quota) {
+       if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
                spin_lock(&user->lock);
                user->qnkeys--;
                user->qnbytes -= quotalen;
 no_memory_3:
        kmem_cache_free(key_jar, key);
 no_memory_2:
-       if (!not_in_quota) {
+       if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
                spin_lock(&user->lock);
                user->qnkeys--;
                user->qnbytes -= quotalen;
                               const char *description,
                               const void *payload,
                               size_t plen,
-                              int not_in_quota)
+                              unsigned long flags)
 {
        struct key_type *ktype;
        struct key *keyring, *key = NULL;
 
        /* allocate a new key */
        key = key_alloc(ktype, description, current->fsuid, current->fsgid,
-                       current, perm, not_in_quota);
+                       current, perm, flags);
        if (IS_ERR(key)) {
                key_ref = ERR_PTR(PTR_ERR(key));
                goto error_3;
 
        /* create or update the requested key and add it to the target
         * keyring */
        key_ref = key_create_or_update(keyring_ref, type, description,
-                                      payload, plen, 0);
+                                      payload, plen, KEY_ALLOC_IN_QUOTA);
        if (!IS_ERR(key_ref)) {
                ret = key_ref_to_ptr(key_ref)->serial;
                key_ref_put(key_ref);
 
        /* do the search */
        key = request_key_and_link(ktype, description, callout_info,
-                                  key_ref_to_ptr(dest_ref));
+                                  key_ref_to_ptr(dest_ref),
+                                  KEY_ALLOC_IN_QUOTA);
        if (IS_ERR(key)) {
                ret = PTR_ERR(key);
                goto error5;
 
  * allocate a keyring and link into the destination keyring
  */
 struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
-                         struct task_struct *ctx, int not_in_quota,
+                         struct task_struct *ctx, unsigned long flags,
                          struct key *dest)
 {
        struct key *keyring;
        keyring = key_alloc(&key_type_keyring, description,
                            uid, gid, ctx,
                            (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
-                           not_in_quota);
+                           flags);
 
        if (!IS_ERR(keyring)) {
                ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
 
        /* 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;
         * 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);
 
        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;
        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;
 static int install_session_keyring(struct task_struct *tsk,
                                   struct key *keyring)
 {
+       unsigned long flags;
        struct key *old;
        char buf[20];
 
        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);
        }
        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;
 
        /* allocate a new session keyring */
        sprintf(desc, "_req.%u", key->serial);
 
-       keyring = keyring_alloc(desc, current->fsuid, current->fsgid,
-                               current, 1, NULL);
+       keyring = keyring_alloc(desc, current->fsuid, current->fsgid, current,
+                               KEY_ALLOC_QUOTA_OVERRUN, NULL);
        if (IS_ERR(keyring)) {
                ret = PTR_ERR(keyring);
                goto error_alloc;
  */
 static struct key *__request_key_construction(struct key_type *type,
                                              const char *description,
-                                             const char *callout_info)
+                                             const char *callout_info,
+                                             unsigned long flags)
 {
        request_key_actor_t actor;
        struct key_construction cons;
        struct key *key, *authkey;
        int ret, negated;
 
-       kenter("%s,%s,%s", type->name, description, callout_info);
+       kenter("%s,%s,%s,%lx", type->name, description, callout_info, flags);
 
        /* create a key and add it to the queue */
        key = key_alloc(type, description,
-                       current->fsuid, current->fsgid,
-                       current, KEY_POS_ALL, 0);
+                       current->fsuid, current->fsgid, current, KEY_POS_ALL,
+                       flags);
        if (IS_ERR(key))
                goto alloc_failed;
 
 static struct key *request_key_construction(struct key_type *type,
                                            const char *description,
                                            struct key_user *user,
-                                           const char *callout_info)
+                                           const char *callout_info,
+                                           unsigned long flags)
 {
        struct key_construction *pcons;
        struct key *key, *ckey;
 
        DECLARE_WAITQUEUE(myself, current);
 
-       kenter("%s,%s,{%d},%s",
-              type->name, description, user->uid, callout_info);
+       kenter("%s,%s,{%d},%s,%lx",
+              type->name, description, user->uid, callout_info, flags);
 
        /* see if there's such a key under construction already */
        down_write(&key_construction_sem);
        }
 
        /* see about getting userspace to construct the key */
-       key = __request_key_construction(type, description, callout_info);
+       key = __request_key_construction(type, description, callout_info,
+                                        flags);
  error:
        kleave(" = %p", key);
        return key;
 struct key *request_key_and_link(struct key_type *type,
                                 const char *description,
                                 const char *callout_info,
-                                struct key *dest_keyring)
+                                struct key *dest_keyring,
+                                unsigned long flags)
 {
        struct key_user *user;
        struct key *key;
        key_ref_t key_ref;
 
-       kenter("%s,%s,%s,%p",
-              type->name, description, callout_info, dest_keyring);
+       kenter("%s,%s,%s,%p,%lx",
+              type->name, description, callout_info, dest_keyring, flags);
 
        /* search all the process keyrings for a key */
        key_ref = search_process_keyrings(type, description, type->match,
                        /* ask userspace (returns NULL if it waited on a key
                         * being constructed) */
                        key = request_key_construction(type, description,
-                                                      user, callout_info);
+                                                      user, callout_info,
+                                                      flags);
                        if (key)
                                break;
 
                        const char *description,
                        const char *callout_info)
 {
-       return request_key_and_link(type, description, callout_info, NULL);
+       return request_key_and_link(type, description, callout_info, NULL,
+                                   KEY_ALLOC_IN_QUOTA);
 
 } /* end request_key() */
 
 
        authkey = key_alloc(&key_type_request_key_auth, desc,
                            current->fsuid, current->fsgid, current,
                            KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
-                           KEY_USR_VIEW, 1);
+                           KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA);
        if (IS_ERR(authkey)) {
                ret = PTR_ERR(authkey);
                goto error_alloc;
 
 
 #ifdef CONFIG_KEYS
 
-static int selinux_key_alloc(struct key *k, struct task_struct *tsk)
+static int selinux_key_alloc(struct key *k, struct task_struct *tsk,
+                            unsigned long flags)
 {
        struct task_security_struct *tsec = tsk->security;
        struct key_security_struct *ksec;
 
 #ifdef CONFIG_KEYS
        /* Add security information to initial keyrings */
-       security_key_alloc(&root_user_keyring, current);
-       security_key_alloc(&root_session_keyring, current);
+       security_key_alloc(&root_user_keyring, current,
+                          KEY_ALLOC_NOT_IN_QUOTA);
+       security_key_alloc(&root_session_keyring, current,
+                          KEY_ALLOC_NOT_IN_QUOTA);
 #endif
 
        return 0;