1
0

msm: camera: isp: validate in_port before accessing

in_port information we are getting from the UMD and accessing
it directly without validation which might lead to
corruption and device failure.

CRs-Fixed: 2629969
Change-Id: I0a1c57db9b94f9657427872ae6797635c6aed668
Signed-off-by: Tejas Prajapati <tpraja@codeaurora.org>
Este cometimento está contido em:
Tejas Prajapati
2020-03-26 13:24:42 +05:30
cometido por Gerrit - the friendly Code Review server
ascendente 1b7fd53958
cometimento bb88411486

Ver ficheiro

@@ -2110,18 +2110,36 @@ err:
static int cam_ife_mgr_check_and_update_fe_v0(
struct cam_ife_hw_mgr_ctx *ife_ctx,
struct cam_isp_acquire_hw_info *acquire_hw_info)
struct cam_isp_acquire_hw_info *acquire_hw_info,
uint32_t acquire_info_size)
{
int i;
struct cam_isp_in_port_info *in_port = NULL;
uint32_t in_port_length = 0;
uint32_t total_in_port_length = 0;
if (acquire_hw_info->input_info_offset >=
acquire_hw_info->input_info_size) {
CAM_ERR(CAM_ISP,
"Invalid size offset 0x%x is greater then size 0x%x",
acquire_hw_info->input_info_offset,
acquire_hw_info->input_info_size);
return -EINVAL;
}
in_port = (struct cam_isp_in_port_info *)
((uint8_t *)&acquire_hw_info->data +
acquire_hw_info->input_info_offset);
for (i = 0; i < acquire_hw_info->num_inputs; i++) {
if (((uint8_t *)in_port +
sizeof(struct cam_isp_in_port_info)) >
((uint8_t *)acquire_hw_info +
acquire_info_size)) {
CAM_ERR(CAM_ISP, "Invalid size");
return -EINVAL;
}
if ((in_port->num_out_res > CAM_IFE_HW_OUT_RES_MAX) ||
(in_port->num_out_res <= 0)) {
CAM_ERR(CAM_ISP, "Invalid num output res %u",
@@ -2155,18 +2173,36 @@ static int cam_ife_mgr_check_and_update_fe_v0(
static int cam_ife_mgr_check_and_update_fe_v2(
struct cam_ife_hw_mgr_ctx *ife_ctx,
struct cam_isp_acquire_hw_info *acquire_hw_info)
struct cam_isp_acquire_hw_info *acquire_hw_info,
uint32_t acquire_info_size)
{
int i;
struct cam_isp_in_port_info_v2 *in_port = NULL;
uint32_t in_port_length = 0;
uint32_t total_in_port_length = 0;
if (acquire_hw_info->input_info_offset >=
acquire_hw_info->input_info_size) {
CAM_ERR(CAM_ISP,
"Invalid size offset 0x%x is greater then size 0x%x",
acquire_hw_info->input_info_offset,
acquire_hw_info->input_info_size);
return -EINVAL;
}
in_port = (struct cam_isp_in_port_info_v2 *)
((uint8_t *)&acquire_hw_info->data +
acquire_hw_info->input_info_offset);
for (i = 0; i < acquire_hw_info->num_inputs; i++) {
if (((uint8_t *)in_port +
sizeof(struct cam_isp_in_port_info)) >
((uint8_t *)acquire_hw_info +
acquire_info_size)) {
CAM_ERR(CAM_ISP, "Invalid size");
return -EINVAL;
}
if ((in_port->num_out_res > CAM_IFE_HW_OUT_RES_MAX) ||
(in_port->num_out_res <= 0)) {
CAM_ERR(CAM_ISP, "Invalid num output res %u",
@@ -2203,7 +2239,8 @@ static int cam_ife_mgr_check_and_update_fe_v2(
static int cam_ife_mgr_check_and_update_fe(
struct cam_ife_hw_mgr_ctx *ife_ctx,
struct cam_isp_acquire_hw_info *acquire_hw_info)
struct cam_isp_acquire_hw_info *acquire_hw_info,
uint32_t acquire_info_size)
{
uint32_t major_ver = 0, minor_ver = 0;
@@ -2216,10 +2253,10 @@ static int cam_ife_mgr_check_and_update_fe(
switch (major_ver) {
case 1:
return cam_ife_mgr_check_and_update_fe_v0(
ife_ctx, acquire_hw_info);
ife_ctx, acquire_hw_info, acquire_info_size);
case 2:
return cam_ife_mgr_check_and_update_fe_v2(
ife_ctx, acquire_hw_info);
ife_ctx, acquire_hw_info, acquire_info_size);
break;
default:
CAM_ERR(CAM_ISP, "Invalid ver of common info from user");
@@ -3014,7 +3051,8 @@ static int cam_ife_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
acquire_hw_info =
(struct cam_isp_acquire_hw_info *)acquire_args->acquire_info;
rc = cam_ife_mgr_check_and_update_fe(ife_ctx, acquire_hw_info);
rc = cam_ife_mgr_check_and_update_fe(ife_ctx, acquire_hw_info,
acquire_args->acquire_info_size);
if (rc) {
CAM_ERR(CAM_ISP, "buffer size is not enough");
goto free_cdm;