keys: ensure that ->match_free() is called in request_key_and_link()
[sfrench/cifs-2.6.git] / security / keys / request_key.c
index 46c5187ce03fa4483fbe6ea7cd67991be15b5a00..957b9e3e14924dff2c3ad5d8e647d77f9eff6860 100644 (file)
@@ -135,7 +135,8 @@ static int call_sbin_request_key(struct key *authkey, void *aux)
 
        cred = get_current_cred();
        keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
-                               NULL, KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL);
+                               KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
+                               KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL);
        put_cred(cred);
        if (IS_ERR(keyring)) {
                ret = PTR_ERR(keyring);
@@ -366,11 +367,11 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
                               struct key *dest_keyring,
                               unsigned long flags,
                               struct key_user *user,
-                              struct key_acl *acl,
                               struct key **_key)
 {
        struct assoc_array_edit *edit = NULL;
        struct key *key;
+       key_perm_t perm;
        key_ref_t key_ref;
        int ret;
 
@@ -380,9 +381,17 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
        *_key = NULL;
        mutex_lock(&user->cons_lock);
 
+       perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
+       perm |= KEY_USR_VIEW;
+       if (ctx->index_key.type->read)
+               perm |= KEY_POS_READ;
+       if (ctx->index_key.type == &key_type_keyring ||
+           ctx->index_key.type->update)
+               perm |= KEY_POS_WRITE;
+
        key = key_alloc(ctx->index_key.type, ctx->index_key.description,
                        ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred,
-                       acl, flags, NULL);
+                       perm, flags, NULL);
        if (IS_ERR(key))
                goto alloc_failed;
 
@@ -465,7 +474,6 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx,
                                          const char *callout_info,
                                          size_t callout_len,
                                          void *aux,
-                                         struct key_acl *acl,
                                          struct key *dest_keyring,
                                          unsigned long flags)
 {
@@ -488,7 +496,7 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx,
                goto error_put_dest_keyring;
        }
 
-       ret = construct_alloc_key(ctx, dest_keyring, flags, user, acl, &key);
+       ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key);
        key_user_put(user);
 
        if (ret == 0) {
@@ -526,7 +534,6 @@ error:
  * @callout_info: The data to pass to the instantiation upcall (or NULL).
  * @callout_len: The length of callout_info.
  * @aux: Auxiliary data for the upcall.
- * @acl: The ACL to attach if a new key is created.
  * @dest_keyring: Where to cache the key.
  * @flags: Flags to key_alloc().
  *
@@ -554,7 +561,6 @@ struct key *request_key_and_link(struct key_type *type,
                                 const void *callout_info,
                                 size_t callout_len,
                                 void *aux,
-                                struct key_acl *acl,
                                 struct key *dest_keyring,
                                 unsigned long flags)
 {
@@ -589,7 +595,7 @@ struct key *request_key_and_link(struct key_type *type,
 
        key = check_cached_key(&ctx);
        if (key)
-               return key;
+               goto error_free;
 
        /* search all the process keyrings for a key */
        rcu_read_lock();
@@ -629,7 +635,7 @@ struct key *request_key_and_link(struct key_type *type,
                        goto error_free;
 
                key = construct_key_and_link(&ctx, callout_info, callout_len,
-                                            aux, acl, dest_keyring, flags);
+                                            aux, dest_keyring, flags);
        }
 
 error_free:
@@ -672,7 +678,6 @@ EXPORT_SYMBOL(wait_for_key_construction);
  * @description: The searchable description of the key.
  * @domain_tag: The domain in which the key operates.
  * @callout_info: The data to pass to the instantiation upcall (or NULL).
- * @acl: The ACL to attach if a new key is created.
  *
  * As for request_key_and_link() except that it does not add the returned key
  * to a keyring if found, new keys are always allocated in the user's quota,
@@ -685,8 +690,7 @@ EXPORT_SYMBOL(wait_for_key_construction);
 struct key *request_key_tag(struct key_type *type,
                            const char *description,
                            struct key_tag *domain_tag,
-                           const char *callout_info,
-                           struct key_acl *acl)
+                           const char *callout_info)
 {
        struct key *key;
        size_t callout_len = 0;
@@ -696,7 +700,7 @@ struct key *request_key_tag(struct key_type *type,
                callout_len = strlen(callout_info);
        key = request_key_and_link(type, description, domain_tag,
                                   callout_info, callout_len,
-                                  NULL, acl, NULL, KEY_ALLOC_IN_QUOTA);
+                                  NULL, NULL, KEY_ALLOC_IN_QUOTA);
        if (!IS_ERR(key)) {
                ret = wait_for_key_construction(key, false);
                if (ret < 0) {
@@ -716,7 +720,6 @@ EXPORT_SYMBOL(request_key_tag);
  * @callout_info: The data to pass to the instantiation upcall (or NULL).
  * @callout_len: The length of callout_info.
  * @aux: Auxiliary data for the upcall.
- * @acl: The ACL to attach if a new key is created.
  *
  * As for request_key_and_link() except that it does not add the returned key
  * to a keyring if found and new keys are always allocated in the user's quota.
@@ -729,15 +732,14 @@ struct key *request_key_with_auxdata(struct key_type *type,
                                     struct key_tag *domain_tag,
                                     const void *callout_info,
                                     size_t callout_len,
-                                    void *aux,
-                                    struct key_acl *acl)
+                                    void *aux)
 {
        struct key *key;
        int ret;
 
        key = request_key_and_link(type, description, domain_tag,
                                   callout_info, callout_len,
-                                  aux, acl, NULL, KEY_ALLOC_IN_QUOTA);
+                                  aux, NULL, KEY_ALLOC_IN_QUOTA);
        if (!IS_ERR(key)) {
                ret = wait_for_key_construction(key, false);
                if (ret < 0) {