Merge "msm: camera: jpeg: Avoid UAF in jpeg driver" into camera-kernel.lnx.7.0
This commit is contained in:
commit
179c50c49e
@ -106,10 +106,6 @@ static int cam_jpeg_add_command_buffers(struct cam_packet *packet,
|
||||
struct cam_cmd_buf_desc *cmd_desc = NULL;
|
||||
struct cam_jpeg_request_data *jpeg_request_data;
|
||||
struct cam_kmd_buf_info kmd_buf;
|
||||
struct cam_jpeg_config_inout_param_info *inout_params;
|
||||
uint32_t *cmd_buf_kaddr;
|
||||
uintptr_t kaddr;
|
||||
size_t len;
|
||||
unsigned int num_entry = 0;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
@ -157,9 +153,10 @@ static int cam_jpeg_add_command_buffers(struct cam_packet *packet,
|
||||
num_entry++;
|
||||
|
||||
jpeg_request_data->dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
|
||||
jpeg_request_data->encode_size_buffer_ptr = NULL;
|
||||
jpeg_request_data->request_id = packet->header.request_id;
|
||||
jpeg_request_data->thumbnail_threshold_size = 0;
|
||||
jpeg_request_data->out_size_mem_handle = 0;
|
||||
jpeg_request_data->out_size_offset = 0;
|
||||
|
||||
CAM_DBG(CAM_JPEG,
|
||||
"Change_Base HW_Entry. Offset: 0x%x Length: %u mem_handle: 0x%x num_entry: %d",
|
||||
@ -193,29 +190,8 @@ static int cam_jpeg_add_command_buffers(struct cam_packet *packet,
|
||||
num_entry++;
|
||||
break;
|
||||
case CAM_JPEG_PACKET_INOUT_PARAM:
|
||||
rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
|
||||
(uintptr_t *)&kaddr, &len);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_JPEG, "unable to get info for cmd buf: %x %d");
|
||||
return rc;
|
||||
}
|
||||
|
||||
cmd_buf_kaddr = (uint32_t *)kaddr;
|
||||
|
||||
if (cmd_desc[i].offset >= len) {
|
||||
CAM_ERR(CAM_JPEG, "Invalid offset: %u cmd buf len: %zu",
|
||||
cmd_desc[i].offset, len);
|
||||
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
cmd_buf_kaddr += (cmd_desc[i].offset / sizeof(uint32_t));
|
||||
|
||||
inout_params = (struct cam_jpeg_config_inout_param_info *)cmd_buf_kaddr;
|
||||
jpeg_request_data->encode_size_buffer_ptr = &inout_params->output_size;
|
||||
CAM_DBG(CAM_JPEG, "encode_size_buf_ptr: 0x%p",
|
||||
jpeg_request_data->encode_size_buffer_ptr);
|
||||
cam_mem_put_cpu_buf(cmd_desc[i].mem_handle);
|
||||
jpeg_request_data->out_size_mem_handle = cmd_desc[i].mem_handle;
|
||||
jpeg_request_data->out_size_offset = cmd_desc[i].offset;
|
||||
break;
|
||||
case CAM_JPEG_PACKET_GENERIC_BLOB:
|
||||
rc = cam_packet_util_process_generic_cmd_buffer(&cmd_desc[i],
|
||||
@ -391,6 +367,11 @@ static int cam_jpeg_mgr_bottom_half_irq(void *priv, void *data)
|
||||
struct cam_ctx_request *req;
|
||||
struct cam_jpeg_misr_dump_args misr_args;
|
||||
struct cam_jpeg_hw_buf_done_evt_data jpeg_done_evt;
|
||||
struct cam_jpeg_config_inout_param_info *inout_params;
|
||||
uint32_t *cmd_buf_kaddr;
|
||||
uintptr_t kaddr;
|
||||
size_t len;
|
||||
size_t inout_param_size;
|
||||
|
||||
if (!data || !priv) {
|
||||
CAM_ERR(CAM_JPEG, "Invalid data");
|
||||
@ -467,10 +448,26 @@ static int cam_jpeg_mgr_bottom_half_irq(void *priv, void *data)
|
||||
}
|
||||
|
||||
jpeg_req = irq_cb_data->jpeg_req;
|
||||
inout_param_size = sizeof(struct cam_jpeg_config_inout_param_info);
|
||||
|
||||
if (jpeg_req->dev_type == CAM_JPEG_RES_TYPE_ENC) {
|
||||
if (jpeg_req->encode_size_buffer_ptr)
|
||||
*jpeg_req->encode_size_buffer_ptr = task_data->u.output_encode_size;
|
||||
rc = cam_mem_get_cpu_buf(jpeg_req->out_size_mem_handle,
|
||||
(uintptr_t *)&kaddr, &len);
|
||||
if (!rc) {
|
||||
if ((inout_param_size > len) ||
|
||||
(jpeg_req->out_size_offset >= (len - inout_param_size)))
|
||||
CAM_ERR(CAM_JPEG,
|
||||
"Inval off = %u cmd buf len = %zu inout_param_size = %d",
|
||||
jpeg_req->out_size_offset, len, inout_param_size);
|
||||
else {
|
||||
cmd_buf_kaddr = (uint32_t *)kaddr;
|
||||
cmd_buf_kaddr += (jpeg_req->out_size_offset / sizeof(uint32_t));
|
||||
inout_params =
|
||||
(struct cam_jpeg_config_inout_param_info *)cmd_buf_kaddr;
|
||||
inout_params->output_size = task_data->u.output_encode_size;
|
||||
}
|
||||
cam_mem_put_cpu_buf(jpeg_req->out_size_mem_handle);
|
||||
}
|
||||
else
|
||||
CAM_ERR(CAM_JPEG, "Buffer pointer for inout param is null");
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022,2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef CAM_JPEG_HW_MGR_INTF_H
|
||||
@ -23,15 +23,16 @@ enum cam_jpeg_hw_type {
|
||||
* struct cam_jpeg_request_data - Jpeg request data received from command buffers
|
||||
* @dev_type : Jpeg device type(ENC vs DMA)
|
||||
* @request_id : Request ID
|
||||
* @encode_size_buffer_ptr : Pointer to the buffer location for storing the encode
|
||||
size of the result
|
||||
* @thumbnail_threshold_size : Threshold size for thumbnail image
|
||||
* @out_size_mem_handle : handle to the buffer to share encoded output size with userspace
|
||||
* @out_size_offset : offset to memory where out_size_mem_handle is stored
|
||||
*/
|
||||
struct cam_jpeg_request_data {
|
||||
uint32_t dev_type;
|
||||
uint64_t request_id;
|
||||
uint32_t *encode_size_buffer_ptr;
|
||||
uint32_t thumbnail_threshold_size;
|
||||
__s32 out_size_mem_handle;
|
||||
uint32_t out_size_offset;
|
||||
};
|
||||
|
||||
typedef void (*cam_jpeg_mini_dump_cb)(void *priv, void *dst);
|
||||
|
Loading…
Reference in New Issue
Block a user