summaryrefslogtreecommitdiff
path: root/drivers/staging/vc04_services
diff options
context:
space:
mode:
authorDan Carpenter <dan.carpenter@oracle.com>2019-05-15 12:38:33 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-06-09 09:18:18 +0200
commitf5a14bba22ae32bb075617d3afb0f1eb4d6f3444 (patch)
tree2c47868e85fe83e82eb8708c789cc8bc66e948ce /drivers/staging/vc04_services
parentb69101c243a20781c7c0839c0026bc5dfe18fcea (diff)
staging: vc04_services: prevent integer overflow in create_pagelist()
commit ca641bae6da977d638458e78cd1487b6160a2718 upstream. The create_pagelist() "count" parameter comes from the user in vchiq_ioctl() and it could overflow. If you look at how create_page() is called in vchiq_prepare_bulk_data(), then the "size" variable is an int so it doesn't make sense to allow negatives or larger than INT_MAX. I don't know this code terribly well, but I believe that typical values of "count" are typically quite low and I don't think this check will affect normal valid uses at all. The "pagelist_size" calculation can also overflow on 32 bit systems, but not on 64 bit systems. I have added an integer overflow check for that as well. The Raspberry PI doesn't offer the same level of memory protection that x86 does so these sorts of bugs are probably not super critical to fix. Fixes: 71bad7f08641 ("staging: add bcm2708 vchiq driver") Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/vc04_services')
-rw-r--r--drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
index be08849175ea..0634676e6f22 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
@@ -405,9 +405,18 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
int dma_buffers;
dma_addr_t dma_addr;
+ if (count >= INT_MAX - PAGE_SIZE)
+ return NULL;
+
offset = ((unsigned int)(unsigned long)buf & (PAGE_SIZE - 1));
num_pages = DIV_ROUND_UP(count + offset, PAGE_SIZE);
+ if (num_pages > (SIZE_MAX - sizeof(PAGELIST_T) -
+ sizeof(struct vchiq_pagelist_info)) /
+ (sizeof(u32) + sizeof(pages[0]) +
+ sizeof(struct scatterlist)))
+ return NULL;
+
pagelist_size = sizeof(PAGELIST_T) +
(num_pages * sizeof(u32)) +
(num_pages * sizeof(pages[0]) +