aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJorgen Hansen <jhansen@vmware.com>2015-03-02 11:19:11 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-03-25 06:32:15 -0400
commitaa6467f190d32b263f7144239c89c63c922d9ff8 (patch)
tree31c580c58722854adb00b2bd991f8ca17913869c /drivers
parent74b5c297f5ecbef0ca128fa7b385b43f036a7984 (diff)
VMCI: Guard against overflow in queue pair allocation
The current maximum size of a queue in a queue pair is 128 MB. If we increase that in the future, the queue pair allocation routines may run into overflow issues. This change adds additional checks to guard against this. Acked-by: Andy King <acking@vmware.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> Signed-off-by: Jorgen Hansen <jhansen@vmware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/vmw_vmci/vmci_driver.c2
-rw-r--r--drivers/misc/vmw_vmci/vmci_queue_pair.c31
2 files changed, 23 insertions, 10 deletions
diff --git a/drivers/misc/vmw_vmci/vmci_driver.c b/drivers/misc/vmw_vmci/vmci_driver.c
index cf264a1bb149..b823f9a6e464 100644
--- a/drivers/misc/vmw_vmci/vmci_driver.c
+++ b/drivers/misc/vmw_vmci/vmci_driver.c
@@ -113,5 +113,5 @@ module_exit(vmci_drv_exit);
113 113
114MODULE_AUTHOR("VMware, Inc."); 114MODULE_AUTHOR("VMware, Inc.");
115MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface."); 115MODULE_DESCRIPTION("VMware Virtual Machine Communication Interface.");
116MODULE_VERSION("1.1.2.0-k"); 116MODULE_VERSION("1.1.3.0-k");
117MODULE_LICENSE("GPL v2"); 117MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c
index c3849456332e..f42d9c4e4561 100644
--- a/drivers/misc/vmw_vmci/vmci_queue_pair.c
+++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c
@@ -295,12 +295,20 @@ static void *qp_alloc_queue(u64 size, u32 flags)
295{ 295{
296 u64 i; 296 u64 i;
297 struct vmci_queue *queue; 297 struct vmci_queue *queue;
298 const size_t num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1; 298 size_t pas_size;
299 const size_t pas_size = num_pages * sizeof(*queue->kernel_if->u.g.pas); 299 size_t vas_size;
300 const size_t vas_size = num_pages * sizeof(*queue->kernel_if->u.g.vas); 300 size_t queue_size = sizeof(*queue) + sizeof(*queue->kernel_if);
301 const size_t queue_size = 301 const u64 num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1;
302 sizeof(*queue) + sizeof(*queue->kernel_if) + 302
303 pas_size + vas_size; 303 if (num_pages >
304 (SIZE_MAX - queue_size) /
305 (sizeof(*queue->kernel_if->u.g.pas) +
306 sizeof(*queue->kernel_if->u.g.vas)))
307 return NULL;
308
309 pas_size = num_pages * sizeof(*queue->kernel_if->u.g.pas);
310 vas_size = num_pages * sizeof(*queue->kernel_if->u.g.vas);
311 queue_size += pas_size + vas_size;
304 312
305 queue = vmalloc(queue_size); 313 queue = vmalloc(queue_size);
306 if (!queue) 314 if (!queue)
@@ -615,10 +623,15 @@ static int qp_memcpy_from_queue_iov(void *dest,
615static struct vmci_queue *qp_host_alloc_queue(u64 size) 623static struct vmci_queue *qp_host_alloc_queue(u64 size)
616{ 624{
617 struct vmci_queue *queue; 625 struct vmci_queue *queue;
618 const size_t num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1; 626 size_t queue_page_size;
627 const u64 num_pages = DIV_ROUND_UP(size, PAGE_SIZE) + 1;
619 const size_t queue_size = sizeof(*queue) + sizeof(*(queue->kernel_if)); 628 const size_t queue_size = sizeof(*queue) + sizeof(*(queue->kernel_if));
620 const size_t queue_page_size = 629
621 num_pages * sizeof(*queue->kernel_if->u.h.page); 630 if (num_pages > (SIZE_MAX - queue_size) /
631 sizeof(*queue->kernel_if->u.h.page))
632 return NULL;
633
634 queue_page_size = num_pages * sizeof(*queue->kernel_if->u.h.page);
622 635
623 queue = kzalloc(queue_size + queue_page_size, GFP_KERNEL); 636 queue = kzalloc(queue_size + queue_page_size, GFP_KERNEL);
624 if (queue) { 637 if (queue) {