]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - security/keys/key.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[karo-tx-linux.git] / security / keys / key.c
index 46f125aa7fa30713586ac8a3ba990739cae73faa..f76c8a546fd3688e4cc2cadd076e05debe43f9a3 100644 (file)
@@ -27,6 +27,11 @@ DEFINE_SPINLOCK(key_serial_lock);
 struct rb_root key_user_tree; /* tree of quota records indexed by UID */
 DEFINE_SPINLOCK(key_user_lock);
 
+unsigned int key_quota_root_maxkeys = 200;     /* root's key count quota */
+unsigned int key_quota_root_maxbytes = 20000;  /* root's key space quota */
+unsigned int key_quota_maxkeys = 200;          /* general key count quota */
+unsigned int key_quota_maxbytes = 20000;       /* general key space quota */
+
 static LIST_HEAD(key_types_list);
 static DECLARE_RWSEM(key_types_sem);
 
@@ -213,7 +218,7 @@ serial_exists:
  *   instantiate the key or discard it before returning
  */
 struct key *key_alloc(struct key_type *type, const char *desc,
-                     uid_t uid, gid_t gid, struct task_struct *ctx,
+                     uid_t uid, gid_t gid, const struct cred *cred,
                      key_perm_t perm, unsigned long flags)
 {
        struct key_user *user = NULL;
@@ -236,11 +241,16 @@ struct key *key_alloc(struct key_type *type, const char *desc,
        /* check that the user's quota permits allocation of another key and
         * its description */
        if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
+               unsigned maxkeys = (uid == 0) ?
+                       key_quota_root_maxkeys : key_quota_maxkeys;
+               unsigned maxbytes = (uid == 0) ?
+                       key_quota_root_maxbytes : key_quota_maxbytes;
+
                spin_lock(&user->lock);
                if (!(flags & KEY_ALLOC_QUOTA_OVERRUN)) {
-                       if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS ||
-                           user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES
-                           )
+                       if (user->qnkeys + 1 >= maxkeys ||
+                           user->qnbytes + quotalen >= maxbytes ||
+                           user->qnbytes + quotalen < user->qnbytes)
                                goto no_quota;
                }
 
@@ -284,7 +294,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
 #endif
 
        /* let the security module know about the key */
-       ret = security_key_alloc(key, ctx, flags);
+       ret = security_key_alloc(key, cred, flags);
        if (ret < 0)
                goto security_error;
 
@@ -345,11 +355,14 @@ int key_payload_reserve(struct key *key, size_t datalen)
 
        /* contemplate the quota adjustment */
        if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
+               unsigned maxbytes = (key->user->uid == 0) ?
+                       key_quota_root_maxbytes : key_quota_maxbytes;
+
                spin_lock(&key->user->lock);
 
                if (delta > 0 &&
-                   key->user->qnbytes + delta > KEYQUOTA_MAX_BYTES
-                   ) {
+                   (key->user->qnbytes + delta >= maxbytes ||
+                    key->user->qnbytes + delta < key->user->qnbytes)) {
                        ret = -EDQUOT;
                }
                else {
@@ -378,7 +391,7 @@ static int __key_instantiate_and_link(struct key *key,
                                      const void *data,
                                      size_t datalen,
                                      struct key *keyring,
-                                     struct key *instkey)
+                                     struct key *authkey)
 {
        int ret, awaken;
 
@@ -408,8 +421,8 @@ static int __key_instantiate_and_link(struct key *key,
                                ret = __key_link(keyring, key);
 
                        /* disable the authorisation key */
-                       if (instkey)
-                               key_revoke(instkey);
+                       if (authkey)
+                               key_revoke(authkey);
                }
        }
 
@@ -431,14 +444,14 @@ int key_instantiate_and_link(struct key *key,
                             const void *data,
                             size_t datalen,
                             struct key *keyring,
-                            struct key *instkey)
+                            struct key *authkey)
 {
        int ret;
 
        if (keyring)
                down_write(&keyring->sem);
 
-       ret = __key_instantiate_and_link(key, data, datalen, keyring, instkey);
+       ret = __key_instantiate_and_link(key, data, datalen, keyring, authkey);
 
        if (keyring)
                up_write(&keyring->sem);
@@ -456,7 +469,7 @@ EXPORT_SYMBOL(key_instantiate_and_link);
 int key_negate_and_link(struct key *key,
                        unsigned timeout,
                        struct key *keyring,
-                       struct key *instkey)
+                       struct key *authkey)
 {
        struct timespec now;
        int ret, awaken;
@@ -491,8 +504,8 @@ int key_negate_and_link(struct key *key,
                        ret = __key_link(keyring, key);
 
                /* disable the authorisation key */
-               if (instkey)
-                       key_revoke(instkey);
+               if (authkey)
+                       key_revoke(authkey);
        }
 
        mutex_unlock(&key_construction_mutex);
@@ -730,6 +743,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
                               key_perm_t perm,
                               unsigned long flags)
 {
+       const struct cred *cred = current_cred();
        struct key_type *ktype;
        struct key *keyring, *key = NULL;
        key_ref_t key_ref;
@@ -789,8 +803,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
        }
 
        /* allocate a new key */
-       key = key_alloc(ktype, description, current->fsuid, current->fsgid,
-                       current, perm, flags);
+       key = key_alloc(ktype, description, cred->fsuid, cred->fsgid, cred,
+                       perm, flags);
        if (IS_ERR(key)) {
                key_ref = ERR_CAST(key);
                goto error_3;