diff options
author | Anton Ivanov <anton.ivanov@cambridgegreys.com> | 2018-06-05 11:27:30 +0300 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2018-06-10 23:50:13 +0300 |
commit | 4579a1ba692af81da7ea6ce197f8169ddc0c327f (patch) | |
tree | 4eeafbb5943de9e6cdb3c4360363ad88ba131268 /arch | |
parent | cca76c1ad61d08097af5a691195f9a42d72e978f (diff) | |
download | linux-4579a1ba692af81da7ea6ce197f8169ddc0c327f.tar.xz |
um: Fix initialization of vector queues
UML vector drivers could derefence uninitialized memory
when cleaning up after a queue allocation failure.
Fixes: 49da7e64f33e ("High Performance UML Vector Network Driver")
Cc: <stable@vger.kernel.org>
Reported-by: Dan Capenter <dan.carpenter@oracle.com>
Signed-off-by: Anton Ivanov <anton.ivanov@cambridgegreys.com>
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/um/drivers/vector_kern.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index 02168fe25105..8b852928959b 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c @@ -504,15 +504,19 @@ static struct vector_queue *create_queue( result = kmalloc(sizeof(struct vector_queue), GFP_KERNEL); if (result == NULL) - goto out_fail; + return NULL; result->max_depth = max_size; result->dev = vp->dev; result->mmsg_vector = kmalloc( (sizeof(struct mmsghdr) * max_size), GFP_KERNEL); + if (result->mmsg_vector == NULL) + goto out_mmsg_fail; result->skbuff_vector = kmalloc( (sizeof(void *) * max_size), GFP_KERNEL); - if (result->mmsg_vector == NULL || result->skbuff_vector == NULL) - goto out_fail; + if (result->skbuff_vector == NULL) + goto out_skb_fail; + + /* further failures can be handled safely by destroy_queue*/ mmsg_vector = result->mmsg_vector; for (i = 0; i < max_size; i++) { @@ -563,6 +567,11 @@ static struct vector_queue *create_queue( result->head = 0; result->tail = 0; return result; +out_skb_fail: + kfree(result->mmsg_vector); +out_mmsg_fail: + kfree(result); + return NULL; out_fail: destroy_queue(result); return NULL; |