msm: camera: common: Fix invalid packet access

Instead of caching packet address pointer, store packet handle
in page fault req info structutre to obtain packet address through
mem manager to avoid potential access to dangling packet pointer which
resulted from UMD called to free the packet buffer before kernel finishes
handling page fault. If the packet was freed, then querying to get packet
address from memory manager will fail since the mem handle is invalid.
If it is invalid, the page fault handler will return before accessing
the dangling packet.

CRs-Fixed: 3287554
Change-Id: I02bc0c706b64f1dc0d098d8189f2f129a91efba7
Signed-off-by: Sokchetra Eung <quic_eung@quicinc.com>
This commit is contained in:
Sokchetra Eung
2022-09-12 13:36:54 -07:00
committad av Camera Software Integration
förälder df3ff7d33b
incheckning 56cc1d37bc
12 ändrade filer med 132 tillägg och 48 borttagningar

Visa fil

@@ -6092,6 +6092,9 @@ static int __cam_isp_ctx_config_dev_in_top_state(
req_isp->bubble_detected = false;
req_isp->cdm_reset_before_apply = false;
req_isp->hw_update_data.packet = packet;
req->pf_data.packet_handle = cmd->packet_handle;
req->pf_data.packet_offset = cmd->offset;
req->pf_data.req = req;
for (i = 0; i < req_isp->num_fence_map_out; i++) {
rc = cam_sync_get_obj_ref(req_isp->fence_map_out[i].sync_id);

Visa fil

@@ -11924,14 +11924,13 @@ static void cam_ife_mgr_pf_dump(struct cam_ife_hw_mgr_ctx *ctx)
static void cam_ife_mgr_pf_dump_mid_info(
struct cam_ife_hw_mgr_ctx *ctx,
struct cam_hw_cmd_args *hw_cmd_args,
struct cam_isp_hw_intf_data *hw_intf_data)
struct cam_isp_hw_intf_data *hw_intf_data,
struct cam_packet *packet)
{
struct cam_packet *packet;
struct cam_isp_hw_get_cmd_update cmd_update;
struct cam_isp_hw_get_res_for_mid get_res;
int rc = 0;
packet = hw_cmd_args->u.pf_cmd_args->pf_req_info->packet;
get_res.mid = hw_cmd_args->u.pf_cmd_args->pf_args->pf_smmu_info->mid;
cmd_update.cmd_type = CAM_ISP_HW_CMD_GET_RES_FOR_MID;
cmd_update.data = (void *) &get_res;
@@ -11964,12 +11963,17 @@ static void cam_ife_mgr_dump_pf_data(
struct cam_packet *packet;
struct cam_isp_hw_intf_data *hw_intf_data;
struct cam_hw_dump_pf_args *pf_args;
struct cam_hw_mgr_pf_request_info *pf_req_info;
bool *ctx_found;
int i, j;
int i, j, rc;
ctx = (struct cam_ife_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map;
pf_req_info = hw_cmd_args->u.pf_cmd_args->pf_req_info;
rc = cam_packet_util_get_packet_addr(&packet, pf_req_info->packet_handle,
pf_req_info->packet_offset);
if (rc)
return;
packet = hw_cmd_args->u.pf_cmd_args->pf_req_info->packet;
pf_args = hw_cmd_args->u.pf_cmd_args->pf_args;
ctx_found = &(pf_args->pf_context_info.ctx_found);
@@ -11992,7 +11996,8 @@ static void cam_ife_mgr_dump_pf_data(
*/
if (!g_ife_hw_mgr.hw_pid_support) {
if (ctx->base[i].split_id == CAM_ISP_HW_SPLIT_LEFT)
cam_ife_mgr_pf_dump_mid_info(ctx, hw_cmd_args, hw_intf_data);
cam_ife_mgr_pf_dump_mid_info(ctx, hw_cmd_args, hw_intf_data,
packet);
continue;
}
@@ -12002,7 +12007,8 @@ static void cam_ife_mgr_dump_pf_data(
CAM_ERR(CAM_ISP, "PF found for %s%d pid: %u",
ctx->base[i].hw_type == CAM_ISP_HW_TYPE_VFE ? "VFE" : "SFE",
ctx->base[i].idx, pf_args->pf_smmu_info->pid);
cam_ife_mgr_pf_dump_mid_info(ctx, hw_cmd_args, hw_intf_data);
cam_ife_mgr_pf_dump_mid_info(ctx, hw_cmd_args, hw_intf_data,
packet);
/* If MID found - stop hw res and dump client info */
if (ctx->flags.pf_mid_found) {

Visa fil

@@ -4676,7 +4676,10 @@ static void cam_tfe_mgr_dump_pf_data(
ctx = (struct cam_tfe_hw_mgr_ctx *)hw_cmd_args->ctxt_to_hw_map;
pf_cmd_args = hw_cmd_args->u.pf_cmd_args;
packet = pf_cmd_args->pf_req_info->packet;
rc = cam_packet_util_get_packet_addr(packet,
pf_cmd_args->pf_req_info->packet_handle, pf_cmd_args->pf_req_info->packet_offset);
if (rc)
return rc;
ctx_found = &pf_cmd_args->pf_args->pf_context_info.ctx_found;
resource_type = &pf_cmd_args->pf_args->pf_context_info.resource_type;

Visa fil

@@ -756,7 +756,6 @@ int cam_isp_add_io_buffers(
num_out_buf = prepare->num_out_map_entries;
num_in_buf = prepare->num_in_map_entries;
io_cfg_used_bytes = 0;
prepare->pf_data->packet = prepare->packet;
/* Max one hw entries required for each base */
if (prepare->num_hw_update_entries + 1 >=