From bf1ef90457ff6e55450e81db53637a5a9f0420d6 Mon Sep 17 00:00:00 2001 From: Shridhar Rasal Date: Wed, 4 Jan 2017 12:38:33 +0530 Subject: [PATCH] video: tegra: host: dla: fix coverity issues fix coverity issue seen in ioctl argument usage. Validate input arguments for arguments. add missing error messages from pinning path. Bug 1806862 CID 1806862 CID 38902 Change-Id: I025bedbd7060b7ffb7f908c0fb5e6f0d80710530 Signed-off-by: Shridhar Rasal Reviewed-on: http://git-master/r/1280084 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/video/tegra/host/nvdla/nvdla_ioctl.c | 59 ++++++++++++++++++-- drivers/video/tegra/host/nvdla/nvdla_queue.c | 8 +++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/drivers/video/tegra/host/nvdla/nvdla_ioctl.c b/drivers/video/tegra/host/nvdla/nvdla_ioctl.c index 8290236c..ba738b9c 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_ioctl.c +++ b/drivers/video/tegra/host/nvdla/nvdla_ioctl.c @@ -98,9 +98,21 @@ static int nvdla_pin(struct nvdla_private *priv, void *arg) int err = 0; struct nvdla_pin_unpin_args *buf_list = (struct nvdla_pin_unpin_args *)arg; - u32 count = buf_list->num_buffers; + u32 count; struct platform_device *pdev = priv->pdev; + if (!buf_list) { + nvdla_dbg_err(pdev, "Invalid argument ptr in pin\n"); + err = -EINVAL; + goto fail_to_get_val_arg; + } + + count = buf_list->num_buffers; + if (count == 0 || !buf_list->buffers) { + nvdla_dbg_err(pdev, "Inval cnt arg for pin\n"); + err = -EINVAL; + goto fail_to_get_val_cnt; + } nvdla_dbg_info(pdev, "num of buffers [%d]", count); handles = kcalloc(count, sizeof(u32), GFP_KERNEL); @@ -117,6 +129,8 @@ static int nvdla_pin(struct nvdla_private *priv, void *arg) nvdla_buffer_cpy_err: kfree(handles); +fail_to_get_val_cnt: +fail_to_get_val_arg: return err; } @@ -126,9 +140,21 @@ static int nvdla_unpin(struct nvdla_private *priv, void *arg) int err = 0; struct nvdla_pin_unpin_args *buf_list = (struct nvdla_pin_unpin_args *)arg; - u32 count = buf_list->num_buffers; + u32 count; struct platform_device *pdev = priv->pdev; + if (!buf_list) { + nvdla_dbg_err(pdev, "Invalid argument for pointer\n"); + err = -EINVAL; + goto fail_to_get_val_arg; + } + + count = buf_list->num_buffers; + if (count == 0 || !buf_list->buffers) { + nvdla_dbg_err(pdev, "Inval count argument for unpin\n"); + err = -EINVAL; + goto fail_to_get_val_cnt; + } nvdla_dbg_info(pdev, "num of buffers [%d]", count); handles = kcalloc(count, sizeof(u32), GFP_KERNEL); @@ -145,6 +171,8 @@ static int nvdla_unpin(struct nvdla_private *priv, void *arg) nvdla_buffer_cpy_err: kfree(handles); +fail_to_get_val_cnt: +fail_to_get_val_arg: return err; } @@ -155,6 +183,12 @@ static int nvdla_ping(struct platform_device *pdev, u32 *ping_va; int err = 0; + if (!args) { + nvdla_dbg_err(pdev, "Invalid argument for ping\n"); + err = -EINVAL; + goto fail_to_get_val_arg; + } + /* make sure that device is powered on */ err = nvhost_module_busy(pdev); if (err) { @@ -199,7 +233,7 @@ fail_cmd: fail_to_alloc: nvhost_module_idle(pdev); fail_to_on: - +fail_to_get_val_arg: return err; } @@ -346,6 +380,15 @@ static int nvdla_fill_task(struct nvhost_queue *queue, task->buffers = buffers; task->sp = &nvhost_get_host(pdev)->syncpt; + if (local_task->num_prefences > MAX_NUM_NVDLA_PREFENCES || + local_task->num_postfences > MAX_NUM_NVDLA_POSTFENCES || + local_task->num_input_task_status > MAX_NUM_NVDLA_IN_TASK_STATUS || + local_task->num_output_task_status > MAX_NUM_NVDLA_OUT_TASK_STATUS) { + err = -EINVAL; + nvdla_dbg_err(pdev, "Invalid input arguments"); + goto fail_to_get_val_args; + } + task->num_prefences = local_task->num_prefences; task->num_postfences = local_task->num_postfences; task->num_in_task_status = local_task->num_input_task_status; @@ -379,6 +422,7 @@ static int nvdla_fill_task(struct nvhost_queue *queue, return 0; fail_to_get_actions: +fail_to_get_val_args: kfree(task); fail_to_alloc_task: *ptask = NULL; @@ -410,8 +454,10 @@ static int nvdla_submit(struct nvdla_private *priv, void *arg) user_tasks = (struct nvdla_ioctl_submit_task __user *) (uintptr_t)args->tasks; - num_tasks = args->num_tasks; + if (!user_tasks) + return -EINVAL; + num_tasks = args->num_tasks; if (num_tasks == 0 || num_tasks > MAX_TASKS_PER_SUBMIT) return -EINVAL; @@ -494,9 +540,12 @@ static long nvdla_ioctl(struct file *file, unsigned int cmd, } /* copy from user for read commands */ - if (_IOC_DIR(cmd) & _IOC_WRITE) + if (_IOC_DIR(cmd) & _IOC_WRITE) { + if (!arg) + return -EINVAL; if (copy_from_user(buf, (void __user *)arg, _IOC_SIZE(cmd))) return -EFAULT; + } nvdla_dbg_fn(pdev, "priv:%p cmd:%u", priv, cmd); diff --git a/drivers/video/tegra/host/nvdla/nvdla_queue.c b/drivers/video/tegra/host/nvdla/nvdla_queue.c index 252057f6..1767fa1d 100644 --- a/drivers/video/tegra/host/nvdla/nvdla_queue.c +++ b/drivers/video/tegra/host/nvdla/nvdla_queue.c @@ -204,8 +204,11 @@ static int nvdla_map_task_memory(struct nvdla_task *task) struct dma_buf *buf = NULL; struct nvdla_mem_handle *addresses; struct nvhost_buffers *buffers = task->buffers; + struct platform_device *pdev = task->queue->pool->pdev; struct dla_task_descriptor *task_desc = task->task_desc; + nvdla_dbg_fn(pdev, ""); + task->num_handles = 0; /* keep address list always last */ @@ -223,6 +226,7 @@ static int nvdla_map_task_memory(struct nvdla_task *task) GFP_KERNEL); if (!task->memory_handles) { err = -ENOMEM; + nvdla_dbg_err(pdev, "fail to alloc mem handles"); goto fail_to_alloc_handles; } @@ -232,6 +236,7 @@ static int nvdla_map_task_memory(struct nvdla_task *task) GFP_KERNEL); if (!dma_addr) { err = -ENOMEM; + nvdla_dbg_err(pdev, "fail to alloc dma addr list"); goto fail_to_alloc_dma_addr; } @@ -240,6 +245,7 @@ static int nvdla_map_task_memory(struct nvdla_task *task) GFP_KERNEL); if (!dma_size) { err = -ENOMEM; + nvdla_dbg_err(pdev, "fail to alloc dma size"); goto fail_to_alloc_dma_size; } @@ -262,6 +268,7 @@ static int nvdla_map_task_memory(struct nvdla_task *task) ptr = dma_buf_vmap(buf); if (!ptr) { err = -ENOMEM; + nvdla_dbg_err(pdev, "fail to vmap buf"); goto fail_to_pin_mem; } @@ -282,6 +289,7 @@ static int nvdla_map_task_memory(struct nvdla_task *task) err = nvhost_buffer_submit_pin(buffers, task->memory_handles, task->num_handles, dma_addr, dma_size); if (err) { + nvdla_dbg_err(pdev, "fail to submit pin buffers"); goto fail_to_pin_mem; }