From: Eric Biggers <ebiggers@kernel.org>
To: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Linux Crypto Mailing List <linux-crypto@vger.kernel.org>
Subject: Re: [v3 PATCH] crypto: api - Retain alg refcount in crypto_grab_spawn
Date: Sun, 15 Dec 2019 20:46:49 -0800 [thread overview]
Message-ID: <20191216044649.GA908@sol.localdomain> (raw)
In-Reply-To: <20191215041119.ndcodt4bw4rr52es@gondor.apana.org.au>
On Sun, Dec 15, 2019 at 12:11:19PM +0800, Herbert Xu wrote:
> On Sat, Dec 14, 2019 at 02:44:04PM +0800, Herbert Xu wrote:
> >
> > /*
> > - * We may encounter an unregistered instance here, since
> > - * an instance's spawns are set up prior to the instance
> > - * being registered. An unregistered instance will have
> > - * NULL ->cra_users.next, since ->cra_users isn't
> > - * properly initialized until registration. But an
> > - * unregistered instance cannot have any users, so treat
> > - * it the same as ->cra_users being empty.
> > + * We may encounter an unregistered instance
> > + * here, since an instance's spawns are set
> > + * up prior to the instance being registered.
> > + * An unregistered instance cannot have any
> > + * users, so treat it the same as ->cra_users
> > + * being empty.
> > */
> > - if (spawns->next == NULL)
> > + if (!spawn->registered)
> > break;
>
> This is not quite right. spawn->registered only allows us to
> dereference spawn->inst, it doesn't actually mean that inst itself
> is on the cra_list. Here is a better patch:
>
> ---8<---
> This patch changes crypto_grab_spawn to retain the reference count
> on the algorithm. This is because the caller needs to access the
> algorithm parameters and without the reference count the algorithm
> can be freed at any time.
>
> The reference count will be subsequently dropped by the crypto API
> once the instance has been registered. The helper crypto_drop_spawn
> will also conditionally drop the reference count depending on whether
> it has been registered.
>
> Note that the code is actually added to crypto_init_spawn. However,
> unless the caller activates this by setting spawn->dropref beforehand
> then nothing happens. The only caller that sets dropref is currently
> crypto_grab_spawn.
>
> Once all legacy users of crypto_init_spawn disappear, then we can
> kill the dropref flag.
>
> Internally each instance will maintain a list of its spawns prior
> to registration. This memory used by this list is shared with
> other fields that are only used after registration. In order for
> this to work a new flag spawn->registered is added to indicate
> whether spawn->inst can be used.
>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
>
> diff --git a/crypto/algapi.c b/crypto/algapi.c
> index cd643e294664..a2a5372efe1d 100644
> --- a/crypto/algapi.c
> +++ b/crypto/algapi.c
> @@ -124,8 +124,6 @@ static void crypto_remove_instance(struct crypto_instance *inst,
> return;
>
> inst->alg.cra_flags |= CRYPTO_ALG_DEAD;
> - if (hlist_unhashed(&inst->list))
> - return;
>
> if (!tmpl || !crypto_tmpl_get(tmpl))
> return;
> @@ -179,10 +177,14 @@ void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
>
> list_move(&spawn->list, &stack);
>
> - if (&inst->alg == nalg)
> + if (spawn->registered && &inst->alg == nalg)
> break;
There's still code above that uses spawn->inst without verifying that
spawn->registered is set.
inst = spawn->inst;
BUG_ON(&inst->alg == alg);
Also, the below code looks redundant now that it's only executed when
spawn->registered. If it's still needed, maybe the comment needs to be updated?
/*
* We may encounter an unregistered instance here, since
* an instance's spawns are set up prior to the instance
* being registered. An unregistered instance will have
* NULL ->cra_users.next, since ->cra_users isn't
* properly initialized until registration. But an
* unregistered instance cannot have any users, so treat
* it the same as ->cra_users being empty.
*/
if (spawns->next == NULL)
break;
> @@ -700,6 +724,11 @@ void crypto_drop_spawn(struct crypto_spawn *spawn)
> if (!spawn->dead)
> list_del(&spawn->list);
> up_write(&crypto_alg_sem);
> +
> + if (!spawn->dropref || spawn->registered)
> + return;
> +
> + crypto_mod_put(spawn->alg);
> }
> EXPORT_SYMBOL_GPL(crypto_drop_spawn);
How about:
if (spawn->dropref && !spawn->registered)
crypto_mod_put(spawn->alg);
> diff --git a/include/crypto/algapi.h b/include/crypto/algapi.h
> index 771a295ac755..29202b8f12fa 100644
> --- a/include/crypto/algapi.h
> +++ b/include/crypto/algapi.h
> @@ -47,7 +47,13 @@ struct crypto_instance {
> struct crypto_alg alg;
>
> struct crypto_template *tmpl;
> - struct hlist_node list;
> +
> + union {
> + /* List of instances after registration. */
> + struct hlist_node list;
This really should say "Node in list of instances after registration."
Otherwise it sounds like it's a list, not an element of a list.
> + /* List of attached spawns before registration. */
> + struct crypto_spawn *spawns;
> + };
>
- Eric
next prev parent reply other threads:[~2019-12-16 4:46 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-06 6:38 [PATCH 0/4] crypto: api - Retain grabbed refcount until registration Herbert Xu
2019-12-06 6:38 ` [PATCH 1/4] crypto: api - Retain alg refcount in crypto_grab_spawn Herbert Xu
2019-12-06 22:31 ` Eric Biggers
2019-12-06 6:38 ` [PATCH 2/4] crypto: aead - Retain alg refcount in crypto_grab_aead Herbert Xu
2019-12-06 22:41 ` Eric Biggers
2019-12-07 3:30 ` Herbert Xu
2019-12-07 4:52 ` Eric Biggers
2019-12-07 14:55 ` Herbert Xu
2019-12-14 6:44 ` [v2 PATCH] crypto: api - Retain alg refcount in crypto_grab_spawn Herbert Xu
2019-12-15 4:11 ` [v3 " Herbert Xu
2019-12-16 4:46 ` Eric Biggers [this message]
2019-12-18 7:53 ` [v4 " Herbert Xu
2019-12-06 6:38 ` [PATCH 3/4] crypto: akcipher - Retain alg refcount in crypto_grab_akcipher Herbert Xu
2019-12-06 6:38 ` [PATCH 4/4] crypto: skcipher - Retain alg refcount in crypto_grab_skcipher Herbert Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191216044649.GA908@sol.localdomain \
--to=ebiggers@kernel.org \
--cc=herbert@gondor.apana.org.au \
--cc=linux-crypto@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.