diff options
author | Anton Ivanov <anton.ivanov@cambridgegreys.com> | 2018-06-05 04:27:30 -0400 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2018-06-10 16:50:13 -0400 |
commit | 4579a1ba692af81da7ea6ce197f8169ddc0c327f (patch) | |
tree | 4eeafbb5943de9e6cdb3c4360363ad88ba131268 /arch/um | |
parent | cca76c1ad61d08097af5a691195f9a42d72e978f (diff) |
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/um')
-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( | |||
504 | 504 | ||
505 | result = kmalloc(sizeof(struct vector_queue), GFP_KERNEL); | 505 | result = kmalloc(sizeof(struct vector_queue), GFP_KERNEL); |
506 | if (result == NULL) | 506 | if (result == NULL) |
507 | goto out_fail; | 507 | return NULL; |
508 | result->max_depth = max_size; | 508 | result->max_depth = max_size; |
509 | result->dev = vp->dev; | 509 | result->dev = vp->dev; |
510 | result->mmsg_vector = kmalloc( | 510 | result->mmsg_vector = kmalloc( |
511 | (sizeof(struct mmsghdr) * max_size), GFP_KERNEL); | 511 | (sizeof(struct mmsghdr) * max_size), GFP_KERNEL); |
512 | if (result->mmsg_vector == NULL) | ||
513 | goto out_mmsg_fail; | ||
512 | result->skbuff_vector = kmalloc( | 514 | result->skbuff_vector = kmalloc( |
513 | (sizeof(void *) * max_size), GFP_KERNEL); | 515 | (sizeof(void *) * max_size), GFP_KERNEL); |
514 | if (result->mmsg_vector == NULL || result->skbuff_vector == NULL) | 516 | if (result->skbuff_vector == NULL) |
515 | goto out_fail; | 517 | goto out_skb_fail; |
518 | |||
519 | /* further failures can be handled safely by destroy_queue*/ | ||
516 | 520 | ||
517 | mmsg_vector = result->mmsg_vector; | 521 | mmsg_vector = result->mmsg_vector; |
518 | for (i = 0; i < max_size; i++) { | 522 | for (i = 0; i < max_size; i++) { |
@@ -563,6 +567,11 @@ static struct vector_queue *create_queue( | |||
563 | result->head = 0; | 567 | result->head = 0; |
564 | result->tail = 0; | 568 | result->tail = 0; |
565 | return result; | 569 | return result; |
570 | out_skb_fail: | ||
571 | kfree(result->mmsg_vector); | ||
572 | out_mmsg_fail: | ||
573 | kfree(result); | ||
574 | return NULL; | ||
566 | out_fail: | 575 | out_fail: |
567 | destroy_queue(result); | 576 | destroy_queue(result); |
568 | return NULL; | 577 | return NULL; |