aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerome Forissier <jerome.forissier@linaro.org>2015-01-27 18:52:55 +0100
committerJerome Forissier <jerome.forissier@linaro.org>2015-01-28 11:06:30 +0100
commit9f504dbd39efb84805d1abe81d3844cd46954f67 (patch)
treee2be140170f188b8e2d0f5479de4d5a4e7ed0f1a
parent6c1b321c2eecf324d514a8d51b4a22e3ef5e284d (diff)
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 <jerome.forissier@linaro.org> Reviewed-by: Pascal Brand <pascal.brand@linaro.org> Tested-by: Pascal Brand <pascal.brand@linaro.org> (STM platform)
-rw-r--r--generic/tee_mem.c4
-rw-r--r--generic/tee_mem.h2
-rw-r--r--generic/tee_service.c33
-rw-r--r--generic/tee_service.h2
4 files changed, 23 insertions, 18 deletions
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);