diff --git a/drivers/media/platform/tegra/camera/fusa-capture/capture-vi-channel.c b/drivers/media/platform/tegra/camera/fusa-capture/capture-vi-channel.c index 74313136..e0cfca20 100644 --- a/drivers/media/platform/tegra/camera/fusa-capture/capture-vi-channel.c +++ b/drivers/media/platform/tegra/camera/fusa-capture/capture-vi-channel.c @@ -691,7 +691,7 @@ int vi_channel_drv_register( mutex_unlock(&chdrv_lock); 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; device_create(vi_channel_class, dev, devt, NULL, diff --git a/drivers/media/platform/tegra/camera/vi/mc_common.c b/drivers/media/platform/tegra/camera/vi/mc_common.c index ae6b4927..2521a9dd 100644 --- a/drivers/media/platform/tegra/camera/vi/mc_common.c +++ b/drivers/media/platform/tegra/camera/vi/mc_common.c @@ -1,5 +1,5 @@ // 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 */ @@ -226,7 +226,14 @@ int tpg_vi_media_controller_init(struct tegra_mc_vi *mc_vi, int pg_mode) if (!item) 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->vi = mc_vi; diff --git a/drivers/platform/tegra/rtcpu/capture-ivc.c b/drivers/platform/tegra/rtcpu/capture-ivc.c index 65496b8d..3d6ad36c 100644 --- a/drivers/platform/tegra/rtcpu/capture-ivc.c +++ b/drivers/platform/tegra/rtcpu/capture-ivc.c @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2022-2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. #include @@ -477,8 +477,10 @@ static int tegra_capture_ivc_probe(struct tegra_ivc_channel *chan) INIT_LIST_HEAD(&civc->avl_ctx_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++) 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); diff --git a/drivers/platform/tegra/rtcpu/ivc-bus.c b/drivers/platform/tegra/rtcpu/ivc-bus.c index 8d97516a..f8ca40e0 100644 --- a/drivers/platform/tegra/rtcpu/ivc-bus.c +++ b/drivers/platform/tegra/rtcpu/ivc-bus.c @@ -1,5 +1,5 @@ // 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 @@ -97,6 +97,7 @@ static struct tegra_ivc_channel *tegra_ivc_channel_create( u32 version, channel_group, nframes, frame_size, queue_size; const char *service; int ret; + u32 mul = 0U, sum = 0U; struct tegra_ivc_channel *chan = kzalloc(sizeof(*chan), GFP_KERNEL); if (unlikely(chan == NULL)) @@ -151,14 +152,38 @@ static struct tegra_ivc_channel *tegra_ivc_channel_create( 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"); ret = -ENOSPC; goto error; } - queue_size = tegra_ivc_total_queue_size(nframes * frame_size); - if (region->ivc_size + 2 * queue_size > region->size) { + if (__builtin_mul_overflow(nframes, frame_size, &mul)) { + 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"); ret = -ENOSPC; goto error; @@ -217,10 +242,20 @@ static struct tegra_ivc_channel *tegra_ivc_channel_create( tlv->tag = CAMRTC_TAG_IVC_SETUP; 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_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_nframes = nframes; 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; int i; + u32 mul = 0U, sum = 0U; /* Parse out all regions in a node */ for (i = 0; @@ -543,8 +579,20 @@ static int tegra_ivc_bus_parse_regions(struct tegra_ivc_bus *bus, break; } - size += 2 * tegra_ivc_total_queue_size(nframes * - frame_size); + if (__builtin_mul_overflow(nframes, frame_size, &mul)) { + 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); @@ -562,8 +610,10 @@ static int tegra_ivc_bus_parse_regions(struct tegra_ivc_bus *bus, region->config_size = 0; 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", - i, (u32)region->iova, (u32)region->iova + size - 1, + i, (u32)region->iova, sum, size); } diff --git a/drivers/platform/tegra/rtcpu/reset-group.c b/drivers/platform/tegra/rtcpu/reset-group.c index e4603d41..7daeb75c 100644 --- a/drivers/platform/tegra/rtcpu/reset-group.c +++ b/drivers/platform/tegra/rtcpu/reset-group.c @@ -1,5 +1,5 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. #include "reset-group.h" @@ -37,6 +37,7 @@ struct camrtc_reset_group *camrtc_reset_group_get( size_t group_name_len; int index; int ret; + size_t sum = 0U; if (!dev || !dev->of_node) return ERR_PTR(-EINVAL); @@ -50,9 +51,20 @@ struct camrtc_reset_group *camrtc_reset_group_get( if (ret < 0) 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, - offsetof(struct camrtc_reset_group, resets[ret]) + - group_name_len + 1, + sum, GFP_KERNEL); if (!grp) return ERR_PTR(-ENOMEM);