Merge tag 'LA.UM.9.14.1.r1-21700-QCM6490.QISI15.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/camera-kernel into HEAD

"LA.UM.9.14.1.r1-21700-QCM6490.QISI15.0"

* tag 'LA.UM.9.14.1.r1-21700-QCM6490.QISI15.0' of https://git.codelinaro.org/clo/la/platform/vendor/opensource/camera-kernel:
  msm: camera: common: Fix OOB access in bandwidth path handling
  msm: camera: isp: Fix potential illegal access in Acquire HW. Fix for above
  msm: camera: isp: Fix potential illegal access in Acquire HW
  msm: camera: ois: Copy packet header in kernel
  msm: camera: common: Add missing put_cpu_buf calls
  msm: camera: sensor: handling condition for random read
  msm: camera: icp: io buf config num validation
  msm: camera: ope: check cpu buffer offset and cmd buf idx
  msm: camera: sensor: TOCTOU error handling

Change-Id: Ia765f67129e72a2114bd23040a216535acdb3931
This commit is contained in:
Nolen Johnson 2026-08-10 17:11:58 -04:00
commit c491e7d22d
6 changed files with 38 additions and 4 deletions

View file

@ -812,6 +812,7 @@ int cam_node_handle_ioctl(struct cam_node *node, struct cam_control *cmd)
}
case CAM_ACQUIRE_HW: {
uint32_t api_version;
uint32_t struct_version;
void *acquire_ptr = NULL;
size_t acquire_size;
@ -846,6 +847,16 @@ int cam_node_handle_ioctl(struct cam_node *node, struct cam_control *cmd)
}
if (api_version == 1) {
struct_version =
((struct cam_acquire_hw_cmd_v1 *)acquire_ptr)->struct_version;
if (struct_version != api_version) {
CAM_ERR(CAM_CORE,
"Unmatched struct api version %u and struct version %u",
api_version, struct_version);
rc = -EINVAL;
goto acquire_kfree;
}
rc = __cam_node_handle_acquire_hw_v1(node, acquire_ptr);
if (rc) {
CAM_ERR(CAM_CORE,
@ -853,6 +864,16 @@ int cam_node_handle_ioctl(struct cam_node *node, struct cam_control *cmd)
goto acquire_kfree;
}
} else if (api_version == 2) {
struct_version =
((struct cam_acquire_hw_cmd_v2 *)acquire_ptr)->struct_version;
if (struct_version != api_version) {
CAM_ERR(CAM_CORE,
"Unmatched struct api version %u and struct version %u",
api_version, struct_version);
rc = -EINVAL;
goto acquire_kfree;
}
rc = __cam_node_handle_acquire_hw_v2(node, acquire_ptr);
if (rc) {
CAM_ERR(CAM_CORE,

View file

@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2022, The Linux Foundation. All rights reserved.
* Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*/
#include <linux/uaccess.h>

View file

@ -507,8 +507,10 @@ int32_t cam_actuator_i2c_pkt_parse(struct cam_actuator_ctrl_t *a_ctrl,
/* Loop through multiple command buffers */
for (i = 0; i < csl_packet->num_cmd_buf; i++) {
rc = cam_packet_util_validate_cmd_desc(&cmd_desc[i]);
if (rc)
if (rc) {
cam_mem_put_cpu_buf(config.packet_handle);
return rc;
}
total_cmd_buf_in_bytes = cmd_desc[i].length;
if (!total_cmd_buf_in_bytes)

View file

@ -379,6 +379,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
CAM_ERR(CAM_CSIPHY,
"Inval cam_packet strut size: %zu, len_of_buff: %zu",
sizeof(struct cam_packet), len);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
rc = -EINVAL;
return rc;
}
@ -390,6 +391,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
if (cam_packet_util_validate_packet(csl_packet,
remain_len)) {
CAM_ERR(CAM_CSIPHY, "Invalid packet params");
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
rc = -EINVAL;
return rc;
}
@ -400,6 +402,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
csl_packet->cmd_buf_offset / 4);
else {
CAM_ERR(CAM_CSIPHY, "num_cmd_buffers = %d", csl_packet->num_cmd_buf);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
rc = -EINVAL;
return rc;
}
@ -407,6 +410,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
rc = cam_packet_util_validate_cmd_desc(cmd_desc);
if (rc) {
CAM_ERR(CAM_CSIPHY, "Invalid cmd desc ret: %d", rc);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
return rc;
}
@ -415,6 +419,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
if (rc < 0) {
CAM_ERR(CAM_CSIPHY,
"Failed to get cmd buf Mem address : %d", rc);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
return rc;
}
@ -422,6 +427,8 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
(cmd_desc->offset > (len - sizeof(struct cam_csiphy_info)))) {
CAM_ERR(CAM_CSIPHY,
"Not enough buffer provided for cam_cisphy_info");
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
rc = -EINVAL;
return rc;
}
@ -433,6 +440,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
index = cam_csiphy_get_instance_offset(csiphy_dev, cfg_dev->dev_handle);
if (index < 0 || index >= csiphy_dev->session_max_device_support) {
CAM_ERR(CAM_CSIPHY, "index in invalid: %d", index);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return -EINVAL;
}
@ -443,6 +451,7 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
CAM_ERR(CAM_CSIPHY,
"Wrong configuration lane_cnt: %u",
cam_cmd_csiphy_info->lane_cnt);
cam_mem_put_cpu_buf((int32_t)cfg_dev->packet_handle);
cam_mem_put_cpu_buf(cmd_desc->mem_handle);
return rc;
}

View file

@ -556,8 +556,10 @@ int32_t cam_handle_mem_ptr(uint64_t handle, struct cam_sensor_ctrl_t *s_ctrl)
for (i = 0; i < pkt->num_cmd_buf; i++) {
rc = cam_packet_util_validate_cmd_desc(&cmd_desc[i]);
if (rc)
if (rc) {
cam_mem_put_cpu_buf(handle);
return rc;
}
if (!(cmd_desc[i].length))
continue;

View file

@ -316,12 +316,12 @@ static int32_t cam_sensor_get_io_buffer(
(uint8_t *)buf_addr + io_cfg->offsets[0];
i2c_settings->read_buff_len =
buf_size - io_cfg->offsets[0];
cam_mem_put_cpu_buf(io_cfg->mem_handle[0]);
} else {
CAM_ERR(CAM_SENSOR, "Invalid direction: %d",
io_cfg->direction);
rc = -EINVAL;
}
cam_mem_put_cpu_buf(io_cfg->mem_handle[0]);
return rc;
}