From 9f504dbd39efb84805d1abe81d3844cd46954f67 Mon Sep 17 00:00:00 2001 From: Jerome Forissier Date: Tue, 27 Jan 2015 18:52:55 +0100 Subject: tee_shm_allocate(): use size_t for size and check for overflow Fixes failure of xtest 7002 on Foundation_v8 (PLATFORM=vexpress-fvp). xtest 7002 calls TEEC_AllocateSharedMemory() with a requested size of 0xFFFFFFFE and expects an out-of-memory error. Prior to this commit, the size after page_size alignment would wrap to 0 and no error would be returned. Tested on PLATFORM vexpress-fvp and vexpress-qemu_virt. Signed-off-by: Jerome Forissier Reviewed-by: Pascal Brand Tested-by: Pascal Brand (STM platform) --- generic/tee_mem.c | 4 ++-- generic/tee_mem.h | 2 +- generic/tee_service.c | 33 +++++++++++++++++++-------------- generic/tee_service.h | 2 +- 4 files changed, 23 insertions(+), 18 deletions(-) (limited to 'generic') diff --git a/generic/tee_mem.c b/generic/tee_mem.c index 5e46d7f..92c0982 100644 --- a/generic/tee_mem.c +++ b/generic/tee_mem.c @@ -253,7 +253,7 @@ void tee_shm_pool_destroy(struct device *dev, struct shm_pool *pool) dev_dbg(dev, "> poolH(0x%p)\n", (void *)pool); #if defined(_DUMP_INFO_ALLOCATOR) && (_DUMP_INFO_ALLOCATOR > 0) - tee_shm_pool_dump(dev, allocator, true); + tee_shm_pool_dump(dev, pool, true); #endif tee_shm_pool_reset(dev, pool); @@ -543,7 +543,7 @@ failed_out: * */ void tee_shm_pool_free(struct device *dev, struct shm_pool *pool, - unsigned long paddr, uint32_t *size) + unsigned long paddr, size_t *size) { struct mem_chunk *chunk; struct mem_chunk *tmp; diff --git a/generic/tee_mem.h b/generic/tee_mem.h index a7aab93..ed91eb3 100644 --- a/generic/tee_mem.h +++ b/generic/tee_mem.h @@ -42,7 +42,7 @@ unsigned long tee_shm_pool_alloc(struct device *dev, void tee_shm_pool_free(struct device *dev, struct shm_pool *pool, - unsigned long paddr, uint32_t *size); + unsigned long paddr, size_t *size); bool tee_shm_pool_incref(struct device *dev, struct shm_pool *pool, diff --git a/generic/tee_service.c b/generic/tee_service.c index 5fe55b4..78fe38e 100644 --- a/generic/tee_service.c +++ b/generic/tee_service.c @@ -377,7 +377,7 @@ static unsigned long tee_shm_iscontinuous( } struct tee_shm *tee_shm_allocate(struct tee_targetop *op, - void *vaddr, int size, uint32_t flags) + void *vaddr, size_t size, uint32_t flags) { struct device *dev = op->miscdev->this_device; struct tee_shm *shm; @@ -387,14 +387,7 @@ struct tee_shm *tee_shm_allocate(struct tee_targetop *op, struct tee_driver *tee = NULL; tee = tee_get_drvdata(dev); - dev_dbg(dev, "> vaddr:[%p] size:[%d]\n", (void *)vaddr, size); - - shm = (struct tee_shm *)devm_kzalloc(dev, sizeof(struct tee_shm), - GFP_KERNEL); - if (shm == NULL) - return NULL; - - shm->op = op; + dev_dbg(dev, "> vaddr:[%p] size:[%zu]\n", (void *)vaddr, size); /* * Adjust the size in case it is 0 as, from the spec: @@ -411,12 +404,24 @@ struct tee_shm *tee_shm_allocate(struct tee_targetop *op, if ((size % op->page_size) != 0) size = ((size / op->page_size) + 1) * op->page_size; + if (unlikely(size == 0)) { + dev_err(dev, "[%s] requested size too big\n", __func__); + return NULL; + } + + shm = (struct tee_shm *)devm_kzalloc(dev, sizeof(struct tee_shm), + GFP_KERNEL); + if (shm == NULL) + return NULL; + + shm->op = op; + if (vaddr == NULL) { shm->paddr = tee_shm_pool_alloc(dev, op->Allocator, size, op->page_size); if (shm->paddr == 0x0) { - dev_err(dev, "[%s] out of shared memory (%d)\n", + dev_err(dev, "[%s] out of shared memory (%zu)\n", __func__, size); goto out_shm; } @@ -426,7 +431,7 @@ struct tee_shm *tee_shm_allocate(struct tee_targetop *op, } else { shm->paddr = tee_shm_iscontinuous(dev, vaddr, size); if (shm->paddr == 0x0) { - dev_err(dev, "[%s] SHM not contiguous (0x%p + %d)\n", + dev_err(dev, "[%s] SHM not contiguous (0x%p + %zu)\n", __func__, vaddr, size); goto out_shm; } @@ -440,12 +445,12 @@ struct tee_shm *tee_shm_allocate(struct tee_targetop *op, if (list->refcounter == 1) if (op->register_shm(shm->paddr, size, &list->handle) != TEEC_SUCCESS) { - dev_err(dev, "[%s] Cannot register [0x%p] size [%d]\n", + dev_err(dev, "[%s] Cannot register [0x%p] size [%zu]\n", __func__, (void *)shm->paddr, size); goto out_mem; } - dev_dbg(dev, "< %p + %d\n", (void *)shm->paddr, size); + dev_dbg(dev, "< %p + %zd\n", (void *)shm->paddr, size); return shm; out_mem: @@ -465,7 +470,7 @@ void tee_shm_unallocate(struct tee_shm *shm) struct device *dev = shm->op->miscdev->this_device; struct mem_part *part; void *handle; - uint32_t size; + size_t size; struct tee_driver *tee = NULL; unsigned int refcounter = removePhysicalAddr(dev, shm->paddr, &part, &handle); diff --git a/generic/tee_service.h b/generic/tee_service.h index fa2c6ae..316555a 100644 --- a/generic/tee_service.h +++ b/generic/tee_service.h @@ -32,7 +32,7 @@ struct tee_session *tee_create_session(const char *devname, bool userApi); void tee_delete_session(struct tee_session *ts); struct tee_shm *tee_shm_allocate(struct tee_targetop *op, - void *vaddr, int size, uint32_t flags); + void *vaddr, size_t size, uint32_t flags); void tee_shm_unallocate(struct tee_shm *shm); TEEC_Result allocate_uuid(struct tee_session *ts); -- cgit v1.2.3