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_cmd_buf_desc *cmd_desc = NULL;
|
||||||
struct cam_jpeg_request_data *jpeg_request_data;
|
struct cam_jpeg_request_data *jpeg_request_data;
|
||||||
struct cam_kmd_buf_info kmd_buf;
|
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 num_entry = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int rc;
|
int rc;
|
||||||
@ -157,9 +153,10 @@ static int cam_jpeg_add_command_buffers(struct cam_packet *packet,
|
|||||||
num_entry++;
|
num_entry++;
|
||||||
|
|
||||||
jpeg_request_data->dev_type = ctx_data->jpeg_dev_acquire_info.dev_type;
|
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->request_id = packet->header.request_id;
|
||||||
jpeg_request_data->thumbnail_threshold_size = 0;
|
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,
|
CAM_DBG(CAM_JPEG,
|
||||||
"Change_Base HW_Entry. Offset: 0x%x Length: %u mem_handle: 0x%x num_entry: %d",
|
"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++;
|
num_entry++;
|
||||||
break;
|
break;
|
||||||
case CAM_JPEG_PACKET_INOUT_PARAM:
|
case CAM_JPEG_PACKET_INOUT_PARAM:
|
||||||
rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,
|
jpeg_request_data->out_size_mem_handle = cmd_desc[i].mem_handle;
|
||||||
(uintptr_t *)&kaddr, &len);
|
jpeg_request_data->out_size_offset = cmd_desc[i].offset;
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
case CAM_JPEG_PACKET_GENERIC_BLOB:
|
case CAM_JPEG_PACKET_GENERIC_BLOB:
|
||||||
rc = cam_packet_util_process_generic_cmd_buffer(&cmd_desc[i],
|
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_ctx_request *req;
|
||||||
struct cam_jpeg_misr_dump_args misr_args;
|
struct cam_jpeg_misr_dump_args misr_args;
|
||||||
struct cam_jpeg_hw_buf_done_evt_data jpeg_done_evt;
|
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) {
|
if (!data || !priv) {
|
||||||
CAM_ERR(CAM_JPEG, "Invalid data");
|
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;
|
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->dev_type == CAM_JPEG_RES_TYPE_ENC) {
|
||||||
if (jpeg_req->encode_size_buffer_ptr)
|
rc = cam_mem_get_cpu_buf(jpeg_req->out_size_mem_handle,
|
||||||
*jpeg_req->encode_size_buffer_ptr = task_data->u.output_encode_size;
|
(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
|
else
|
||||||
CAM_ERR(CAM_JPEG, "Buffer pointer for inout param is null");
|
CAM_ERR(CAM_JPEG, "Buffer pointer for inout param is null");
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
* 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
|
#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
|
* struct cam_jpeg_request_data - Jpeg request data received from command buffers
|
||||||
* @dev_type : Jpeg device type(ENC vs DMA)
|
* @dev_type : Jpeg device type(ENC vs DMA)
|
||||||
* @request_id : Request ID
|
* @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
|
* @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 {
|
struct cam_jpeg_request_data {
|
||||||
uint32_t dev_type;
|
uint32_t dev_type;
|
||||||
uint64_t request_id;
|
uint64_t request_id;
|
||||||
uint32_t *encode_size_buffer_ptr;
|
|
||||||
uint32_t thumbnail_threshold_size;
|
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);
|
typedef void (*cam_jpeg_mini_dump_cb)(void *priv, void *dst);
|
||||||
|
Loading…
Reference in New Issue
Block a user