mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-08 03:28:15 +07:00
crypto: api - Do not zap spawn->alg
Currently when a spawn is removed we will zap its alg field. This is racy because the spawn could belong to an unregistered instance which may dereference the spawn->alg field. This patch fixes this by keeping spawn->alg constant and instead adding a new spawn->dead field to indicate that a spawn is going away. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
parent
73669cc556
commit
4f87ee118d
@ -93,15 +93,17 @@ static struct list_head *crypto_more_spawns(struct crypto_alg *alg,
|
|||||||
if (!spawn)
|
if (!spawn)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
n = list_next_entry(spawn, list);
|
n = list_prev_entry(spawn, list);
|
||||||
|
|
||||||
if (spawn->alg && &n->list != stack && !n->alg)
|
|
||||||
n->alg = (n->list.next == stack) ? alg :
|
|
||||||
&list_next_entry(n, list)->inst->alg;
|
|
||||||
|
|
||||||
list_move(&spawn->list, secondary_spawns);
|
list_move(&spawn->list, secondary_spawns);
|
||||||
|
|
||||||
return &n->list == stack ? top : &n->inst->alg.cra_users;
|
if (list_is_last(&n->list, stack))
|
||||||
|
return top;
|
||||||
|
|
||||||
|
n = list_next_entry(n, list);
|
||||||
|
if (!spawn->dead)
|
||||||
|
n->dead = false;
|
||||||
|
|
||||||
|
return &n->inst->alg.cra_users;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void crypto_remove_instance(struct crypto_instance *inst,
|
static void crypto_remove_instance(struct crypto_instance *inst,
|
||||||
@ -160,7 +162,7 @@ void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
|
|||||||
if (&inst->alg == nalg)
|
if (&inst->alg == nalg)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
spawn->alg = NULL;
|
spawn->dead = true;
|
||||||
spawns = &inst->alg.cra_users;
|
spawns = &inst->alg.cra_users;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -179,7 +181,7 @@ void crypto_remove_spawns(struct crypto_alg *alg, struct list_head *list,
|
|||||||
&secondary_spawns)));
|
&secondary_spawns)));
|
||||||
|
|
||||||
list_for_each_entry_safe(spawn, n, &secondary_spawns, list) {
|
list_for_each_entry_safe(spawn, n, &secondary_spawns, list) {
|
||||||
if (spawn->alg)
|
if (!spawn->dead)
|
||||||
list_move(&spawn->list, &spawn->alg->cra_users);
|
list_move(&spawn->list, &spawn->alg->cra_users);
|
||||||
else
|
else
|
||||||
crypto_remove_instance(spawn->inst, list);
|
crypto_remove_instance(spawn->inst, list);
|
||||||
@ -670,7 +672,7 @@ EXPORT_SYMBOL_GPL(crypto_grab_spawn);
|
|||||||
void crypto_drop_spawn(struct crypto_spawn *spawn)
|
void crypto_drop_spawn(struct crypto_spawn *spawn)
|
||||||
{
|
{
|
||||||
down_write(&crypto_alg_sem);
|
down_write(&crypto_alg_sem);
|
||||||
if (spawn->alg)
|
if (!spawn->dead)
|
||||||
list_del(&spawn->list);
|
list_del(&spawn->list);
|
||||||
up_write(&crypto_alg_sem);
|
up_write(&crypto_alg_sem);
|
||||||
}
|
}
|
||||||
@ -682,7 +684,7 @@ static struct crypto_alg *crypto_spawn_alg(struct crypto_spawn *spawn)
|
|||||||
|
|
||||||
down_read(&crypto_alg_sem);
|
down_read(&crypto_alg_sem);
|
||||||
alg = spawn->alg;
|
alg = spawn->alg;
|
||||||
if (alg && !crypto_mod_get(alg)) {
|
if (!spawn->dead && !crypto_mod_get(alg)) {
|
||||||
alg->cra_flags |= CRYPTO_ALG_DYING;
|
alg->cra_flags |= CRYPTO_ALG_DYING;
|
||||||
alg = NULL;
|
alg = NULL;
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,7 @@ struct crypto_spawn {
|
|||||||
struct crypto_instance *inst;
|
struct crypto_instance *inst;
|
||||||
const struct crypto_type *frontend;
|
const struct crypto_type *frontend;
|
||||||
u32 mask;
|
u32 mask;
|
||||||
|
bool dead;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct crypto_queue {
|
struct crypto_queue {
|
||||||
|
Loading…
Reference in New Issue
Block a user