linux-crypto.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

  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).