crypto: n2 - cure use after free
commit 203f45003a3d03eea8fa28d74cfc74c354416fdb upstream.
queue_cache_init is first called for the Control Word Queue
(n2_crypto_probe). At that time, queue_cache[0] is NULL and a new
kmem_cache will be allocated. If the subsequent n2_register_algs call
fails, the kmem_cache will be released in queue_cache_destroy, but
queue_cache_init[0] is not set back to NULL.
So when the Module Arithmetic Unit gets probed next (n2_mau_probe),
queue_cache_init will not allocate a kmem_cache again, but leave it
as its bogus value, causing a BUG() to trigger when queue_cache[0] is
eventually passed to kmem_cache_zalloc:
n2_crypto: Found N2CP at /virtual-devices@100/n2cp@7
n2_crypto: Registered NCS HVAPI version 2.0
called queue_cache_init
n2_crypto: md5 alg registration failed
n2cp f028687c: /virtual-devices@100/n2cp@7: Unable to register algorithms.
called queue_cache_destroy
n2cp: probe of f028687c failed with error -22
n2_crypto: Found NCP at /virtual-devices@100/ncp@6
n2_crypto: Registered NCS HVAPI version 2.0
called queue_cache_init
kernel BUG at mm/slab.c:2993!
Call Trace:
[0000000000604488] kmem_cache_alloc+0x1a8/0x1e0
(inlined) kmem_cache_zalloc
(inlined) new_queue
(inlined) spu_queue_setup
(inlined) handle_exec_unit
[0000000010c61eb4] spu_mdesc_scan+0x1f4/0x460 [n2_crypto]
[0000000010c62b80] n2_mau_probe+0x100/0x220 [n2_crypto]
[000000000084b174] platform_drv_probe+0x34/0xc0
Signed-off-by: Jan Engelhardt <jengelh@inai.de>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
790080ce0e
commit
f6db86f31b
@@ -1620,6 +1620,7 @@ static int queue_cache_init(void)
|
|||||||
CWQ_ENTRY_SIZE, 0, NULL);
|
CWQ_ENTRY_SIZE, 0, NULL);
|
||||||
if (!queue_cache[HV_NCS_QTYPE_CWQ - 1]) {
|
if (!queue_cache[HV_NCS_QTYPE_CWQ - 1]) {
|
||||||
kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_MAU - 1]);
|
kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_MAU - 1]);
|
||||||
|
queue_cache[HV_NCS_QTYPE_MAU - 1] = NULL;
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1629,6 +1630,8 @@ static void queue_cache_destroy(void)
|
|||||||
{
|
{
|
||||||
kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_MAU - 1]);
|
kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_MAU - 1]);
|
||||||
kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_CWQ - 1]);
|
kmem_cache_destroy(queue_cache[HV_NCS_QTYPE_CWQ - 1]);
|
||||||
|
queue_cache[HV_NCS_QTYPE_MAU - 1] = NULL;
|
||||||
|
queue_cache[HV_NCS_QTYPE_CWQ - 1] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spu_queue_register(struct spu_queue *p, unsigned long q_type)
|
static int spu_queue_register(struct spu_queue *p, unsigned long q_type)
|
||||||
|
|||||||
Reference in New Issue
Block a user