linux: kmd: static analysis TOP25 03/05 Part 9

Under the following path:
- drivers/media/platform/tegra/camera/fusa-capture/capture-vi-channel.c
- drivers/media/platform/tegra/camera/vi/mc_common.c
- drivers/platform/tegra/rtcpu/capture-ivc.c
- drivers/platform/tegra/rtcpu/ivc-bus.c
- drivers/platform/tegra/rtcpu/reset-group.c

Jira CAMERASW-32533

Change-Id: I4b3d36c77ab09cd930c80fe07846fd9e0e9c28df
Signed-off-by: Zhiyuan Wang <zhiwang@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3314106
Reviewed-by: Frank Chen <frankc@nvidia.com>
Tested-by: Patrick Young <payoung@nvidia.com>
Reviewed-by: Ajith Kumar <ajithk@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Semi Malinen <smalinen@nvidia.com>
This commit is contained in:
Zhiyuan Wang
2025-03-05 03:19:35 -08:00
committed by Jon Hunter
parent bca162a20d
commit c4fb69048c
5 changed files with 89 additions and 18 deletions

View File

@@ -691,7 +691,7 @@ int vi_channel_drv_register(
mutex_unlock(&chdrv_lock); mutex_unlock(&chdrv_lock);
for (i = 0; i < chan_drv->num_channels; i++) { for (i = 0; i < chan_drv->num_channels; i++) {
dev_t devt = MKDEV(vi_channel_major, i); dev_t devt = MKDEV((unsigned long)vi_channel_major, i);
struct device *dev = &chan_drv->vi_capture_pdev->dev; struct device *dev = &chan_drv->vi_capture_pdev->dev;
device_create(vi_channel_class, dev, devt, NULL, device_create(vi_channel_class, dev, devt, NULL,

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2015-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-FileCopyrightText: Copyright (c) 2015-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
/* /*
* Tegra Video Input device common APIs * Tegra Video Input device common APIs
*/ */
@@ -226,7 +226,14 @@ int tpg_vi_media_controller_init(struct tegra_mc_vi *mc_vi, int pg_mode)
if (!item) if (!item)
goto channel_init_error; goto channel_init_error;
item->id = num_pre_channels + i;
if ((__builtin_add_overflow(num_pre_channels, i, &item->id))) {
devm_kfree(mc_vi->dev, item);
dev_err(mc_vi->dev, "failed to add channel id\n");
err = -EOVERFLOW;
goto channel_init_error;
}
item->pg_mode = pg_mode; item->pg_mode = pg_mode;
item->vi = mc_vi; item->vi = mc_vi;

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <nvidia/conftest.h> #include <nvidia/conftest.h>
@@ -477,8 +477,10 @@ static int tegra_capture_ivc_probe(struct tegra_ivc_channel *chan)
INIT_LIST_HEAD(&civc->avl_ctx_list); INIT_LIST_HEAD(&civc->avl_ctx_list);
/* Add the transaction cb-contexts to the available list */ /* Add the transaction cb-contexts to the available list */
mutex_lock(&civc->cb_ctx_lock);
for (i = TRANS_ID_START_IDX; i < ARRAY_SIZE(civc->cb_ctx); i++) for (i = TRANS_ID_START_IDX; i < ARRAY_SIZE(civc->cb_ctx); i++)
list_add_tail(&civc->cb_ctx[i].node, &civc->avl_ctx_list); list_add_tail(&civc->cb_ctx[i].node, &civc->avl_ctx_list);
mutex_unlock(&civc->cb_ctx_lock);
tegra_ivc_channel_set_drvdata(chan, civc); tegra_ivc_channel_set_drvdata(chan, civc);

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
// SPDX-FileCopyrightText: Copyright (c) 2022-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include <nvidia/conftest.h> #include <nvidia/conftest.h>
@@ -97,6 +97,7 @@ static struct tegra_ivc_channel *tegra_ivc_channel_create(
u32 version, channel_group, nframes, frame_size, queue_size; u32 version, channel_group, nframes, frame_size, queue_size;
const char *service; const char *service;
int ret; int ret;
u32 mul = 0U, sum = 0U;
struct tegra_ivc_channel *chan = kzalloc(sizeof(*chan), GFP_KERNEL); struct tegra_ivc_channel *chan = kzalloc(sizeof(*chan), GFP_KERNEL);
if (unlikely(chan == NULL)) if (unlikely(chan == NULL))
@@ -151,14 +152,38 @@ static struct tegra_ivc_channel *tegra_ivc_channel_create(
goto error; goto error;
} }
if (region->config_size + sizeof(*tlv) > CAMRTC_IVC_CONFIG_SIZE) { if (__builtin_add_overflow(region->config_size, sizeof(*tlv), &sum)) {
dev_err(&chan->dev, "IVC config size overflow\n");
ret = -EOVERFLOW;
goto error;
}
if (sum > CAMRTC_IVC_CONFIG_SIZE) {
dev_err(&chan->dev, "IVC config size exceeded\n"); dev_err(&chan->dev, "IVC config size exceeded\n");
ret = -ENOSPC; ret = -ENOSPC;
goto error; goto error;
} }
queue_size = tegra_ivc_total_queue_size(nframes * frame_size); if (__builtin_mul_overflow(nframes, frame_size, &mul)) {
if (region->ivc_size + 2 * queue_size > region->size) { dev_err(&chan->dev, "IVC frame size overflow\n");
ret = -EOVERFLOW;
goto error;
}
queue_size = tegra_ivc_total_queue_size(mul);
if (__builtin_mul_overflow(2U, queue_size, &mul)) {
dev_err(&chan->dev, "IVC queue size overflow\n");
ret = -EOVERFLOW;
goto error;
}
if (__builtin_add_overflow(region->ivc_size, mul, &sum)) {
dev_err(&chan->dev, "IVC size overflow\n");
ret = -EOVERFLOW;
goto error;
}
if (sum > region->size) {
dev_err(&chan->dev, "buffers exceed IVC region\n"); dev_err(&chan->dev, "buffers exceed IVC region\n");
ret = -ENOSPC; ret = -ENOSPC;
goto error; goto error;
@@ -217,10 +242,20 @@ static struct tegra_ivc_channel *tegra_ivc_channel_create(
tlv->tag = CAMRTC_TAG_IVC_SETUP; tlv->tag = CAMRTC_TAG_IVC_SETUP;
tlv->len = sizeof(*tlv); tlv->len = sizeof(*tlv);
tlv->rx_iova = region->iova + start.rx; if (__builtin_add_overflow(region->iova, start.rx, &tlv->rx_iova)) {
dev_err(&chan->dev, "IVC setup overflow\n");
ret = -EOVERFLOW;
goto error;
}
tlv->rx_frame_size = frame_size; tlv->rx_frame_size = frame_size;
tlv->rx_nframes = nframes; tlv->rx_nframes = nframes;
tlv->tx_iova = region->iova + start.tx; if (__builtin_add_overflow(region->iova, start.tx, &tlv->tx_iova)) {
dev_err(&chan->dev, "IVC setup overflow\n");
ret = -EOVERFLOW;
goto error;
}
tlv->tx_frame_size = frame_size; tlv->tx_frame_size = frame_size;
tlv->tx_nframes = nframes; tlv->tx_nframes = nframes;
tlv->channel_group = channel_group; tlv->channel_group = channel_group;
@@ -507,6 +542,7 @@ static int tegra_ivc_bus_parse_regions(struct tegra_ivc_bus *bus,
{ {
struct of_phandle_args reg_spec; struct of_phandle_args reg_spec;
int i; int i;
u32 mul = 0U, sum = 0U;
/* Parse out all regions in a node */ /* Parse out all regions in a node */
for (i = 0; for (i = 0;
@@ -543,8 +579,20 @@ static int tegra_ivc_bus_parse_regions(struct tegra_ivc_bus *bus,
break; break;
} }
size += 2 * tegra_ivc_total_queue_size(nframes * if (__builtin_mul_overflow(nframes, frame_size, &mul)) {
frame_size); dev_err(&bus->dev, "IVC frame size overflow\n");
break;
}
if (__builtin_mul_overflow(2U, tegra_ivc_total_queue_size(mul), &mul)) {
dev_err(&bus->dev, "IVC queue size overflow\n");
break;
}
if (__builtin_add_overflow(size, mul, &size)) {
dev_err(&bus->dev, "IVC size overflow\n");
break;
}
} }
of_node_put(reg_spec.np); of_node_put(reg_spec.np);
@@ -562,8 +610,10 @@ static int tegra_ivc_bus_parse_regions(struct tegra_ivc_bus *bus,
region->config_size = 0; region->config_size = 0;
region->ivc_size = CAMRTC_IVC_CONFIG_SIZE; region->ivc_size = CAMRTC_IVC_CONFIG_SIZE;
(void)(__builtin_add_overflow(region->iova, size, &sum));
(void)(__builtin_sub_overflow(sum, 1U, &sum));
dev_info(&bus->dev, "region %u: iova=0x%x-0x%x size=%u\n", dev_info(&bus->dev, "region %u: iova=0x%x-0x%x size=%u\n",
i, (u32)region->iova, (u32)region->iova + size - 1, i, (u32)region->iova, sum,
size); size);
} }

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0 // SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. // SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
#include "reset-group.h" #include "reset-group.h"
@@ -37,6 +37,7 @@ struct camrtc_reset_group *camrtc_reset_group_get(
size_t group_name_len; size_t group_name_len;
int index; int index;
int ret; int ret;
size_t sum = 0U;
if (!dev || !dev->of_node) if (!dev || !dev->of_node)
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
@@ -50,9 +51,20 @@ struct camrtc_reset_group *camrtc_reset_group_get(
if (ret < 0) if (ret < 0)
return ERR_PTR(-ENOENT); return ERR_PTR(-ENOENT);
if (__builtin_add_overflow(offsetof(struct camrtc_reset_group, resets[ret]),
group_name_len, &sum)) {
dev_err(dev, "Reset group size overflow\n");
return ERR_PTR(-EOVERFLOW);
}
if (__builtin_add_overflow(sum, 1U, &sum)) {
dev_err(dev, "Reset group size overflow\n");
return ERR_PTR(-EOVERFLOW);
}
grp = devres_alloc(camrtc_reset_group_release, grp = devres_alloc(camrtc_reset_group_release,
offsetof(struct camrtc_reset_group, resets[ret]) + sum,
group_name_len + 1,
GFP_KERNEL); GFP_KERNEL);
if (!grp) if (!grp)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);