diff options
author | Abdulla Anam <abdullahanam@codeaurora.org> | 2017-01-25 16:20:37 +0530 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-02-03 04:14:59 -0800 |
commit | cfe8cd7d8a428c49d449f7b1d8ba403aee67c743 (patch) | |
tree | 09154f125011fe10fcfd0aa629f52868abcb5b2c | |
parent | 336e24550387c399c29c3c5a2637c8f29c0a33c7 (diff) |
msm: vidc: Check for sanity of size while mapping buffers
Fail map if dmabuffer size doesn't match expected buffersize.
This is to avoid faults in firmware while accessing buffers.
Change-Id: Ie41a93979696299a8b2fc3c548cb6574a21313db
Signed-off-by: Abdulla Anam <abdullahanam@codeaurora.org>
-rw-r--r-- | drivers/media/platform/msm/vidc/msm_smem.c | 22 | ||||
-rw-r--r-- | drivers/media/platform/msm/vidc/msm_vidc.c | 8 |
2 files changed, 21 insertions, 9 deletions
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c index 44c5c08f074c..c9dfb52861bc 100644 --- a/drivers/media/platform/msm/vidc/msm_smem.c +++ b/drivers/media/platform/msm/vidc/msm_smem.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -75,6 +75,14 @@ static int get_device_address(struct smem_client *smem_client, goto mem_map_failed; } + /* Check if the dmabuf size matches expected size */ + if (buf->size < *buffer_size) { + rc = -EINVAL; + dprintk(VIDC_ERR, + "Size mismatch! Dmabuf size: %zu Expected Size: %lu", + buf->size, *buffer_size); + goto mem_buf_size_mismatch; + } /* Prepare a dma buf for dma on the given device */ attach = dma_buf_attach(buf, cb->dev); if (IS_ERR_OR_NULL(attach)) { @@ -143,6 +151,7 @@ mem_map_sg_failed: dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL); mem_map_table_failed: dma_buf_detach(buf, attach); +mem_buf_size_mismatch: mem_buf_attach_failed: dma_buf_put(buf); mem_map_failed: @@ -193,12 +202,12 @@ static void put_device_address(struct smem_client *smem_client, } } -static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, +static int ion_user_to_kernel(struct smem_client *client, int fd, u32 size, struct msm_smem *mem, enum hal_buffer buffer_type) { struct ion_handle *hndl; ion_phys_addr_t iova = 0; - unsigned long buffer_size = 0; + unsigned long buffer_size = size; int rc = 0; unsigned long align = SZ_4K; unsigned long ion_flags = 0; @@ -207,10 +216,11 @@ static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset, dprintk(VIDC_DBG, "%s ion handle: %pK\n", __func__, hndl); if (IS_ERR_OR_NULL(hndl)) { dprintk(VIDC_ERR, "Failed to get handle: %pK, %d, %d, %pK\n", - client, fd, offset, hndl); + client, fd, size, hndl); rc = -ENOMEM; goto fail_import_fd; } + mem->kvaddr = NULL; rc = ion_handle_get_flags(client->clnt, hndl, &ion_flags); if (rc) { @@ -430,7 +440,7 @@ static void ion_delete_client(struct smem_client *client) ion_client_destroy(client->clnt); } -struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, +struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 size, enum hal_buffer buffer_type) { struct smem_client *client = clt; @@ -447,7 +457,7 @@ struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset, } switch (client->mem_type) { case SMEM_ION: - rc = ion_user_to_kernel(clt, fd, offset, mem, buffer_type); + rc = ion_user_to_kernel(clt, fd, size, mem, buffer_type); break; default: dprintk(VIDC_ERR, "Mem type not supported\n"); diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c index b36e3739e43b..5b98c229b5e1 100644 --- a/drivers/media/platform/msm/vidc/msm_vidc.c +++ b/drivers/media/platform/msm/vidc/msm_vidc.c @@ -364,7 +364,7 @@ static struct msm_smem *map_buffer(struct msm_vidc_inst *inst, struct msm_smem *handle = NULL; handle = msm_comm_smem_user_to_kernel(inst, p->reserved[0], - p->reserved[1], + p->length, buffer_type); if (!handle) { dprintk(VIDC_ERR, @@ -433,8 +433,10 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b) goto exit; } - dprintk(VIDC_DBG, "[MAP] Create binfo = %pK fd = %d type = %d\n", - binfo, b->m.planes[0].reserved[0], b->type); + dprintk(VIDC_DBG, + "[MAP] Create binfo = %pK fd = %d size = %d type = %d\n", + binfo, b->m.planes[0].reserved[0], + b->m.planes[0].length, b->type); for (i = 0; i < b->length; ++i) { rc = 0; |