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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).