msm: camera: sync: Avoid use after free
There is a narrow window, in which the critical section is not fully protected which possibly could lead to use after free. To avoid this, hold the row lock and validate the state prior to processing the dma fence. CRs-Fixed: 3273450 Change-Id: Ib1f09e62a5060a38b5cd8f3d4594bce2e533b3d3 Signed-off-by: Karthik Anantha Ram <quic_kartanan@quicinc.com>
このコミットが含まれているのは:

committed by
Camera Software Integration

コミット
167437bdeb
@@ -1079,8 +1079,9 @@ static int cam_generic_fence_handle_dma_release(
|
||||
rc = cam_dma_fence_release(&release_params);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_DMA_FENCE,
|
||||
"Failed to destroy dma fence at index: %d rc: %d num fences [requested: %u processed: %u]",
|
||||
i, rc, fence_input_info->num_fences_requested,
|
||||
"Failed to destroy dma fence at index: %d fd: %d rc: %d num fences [requested: %u processed: %u]",
|
||||
i, fence_cfg->dma_fence_fd, rc,
|
||||
fence_input_info->num_fences_requested,
|
||||
fence_input_info->num_fences_processed);
|
||||
fence_cfg->reason_code = rc;
|
||||
/* Continue to release other fences, but mark the call as failed */
|
||||
|
@@ -421,6 +421,18 @@ int cam_dma_fence_signal_fd(struct cam_dma_fence_signal *signal_dma_fence)
|
||||
|
||||
spin_lock_bh(&g_cam_dma_fence_dev->row_spinlocks[idx]);
|
||||
row = &g_cam_dma_fence_dev->rows[idx];
|
||||
/*
|
||||
* Check for invalid state again, there could be a contention
|
||||
* between signal and release
|
||||
*/
|
||||
if (row->state == CAM_DMA_FENCE_STATE_INVALID) {
|
||||
spin_unlock_bh(&g_cam_dma_fence_dev->row_spinlocks[idx]);
|
||||
CAM_ERR(CAM_DMA_FENCE,
|
||||
"dma fence fd: %d is invalid row_idx: %u, failed to signal",
|
||||
signal_dma_fence->dma_fence_fd, idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (row->state == CAM_DMA_FENCE_STATE_SIGNALED) {
|
||||
spin_unlock_bh(&g_cam_dma_fence_dev->row_spinlocks[idx]);
|
||||
CAM_WARN(CAM_DMA_FENCE,
|
||||
@@ -535,6 +547,13 @@ static int __cam_dma_fence_release(int32_t dma_row_idx)
|
||||
row = &g_cam_dma_fence_dev->rows[dma_row_idx];
|
||||
dma_fence = row->fence;
|
||||
|
||||
if (row->state == CAM_DMA_FENCE_STATE_INVALID) {
|
||||
spin_unlock_bh(&g_cam_dma_fence_dev->row_spinlocks[dma_row_idx]);
|
||||
CAM_ERR(CAM_DMA_FENCE, "Invalid row index: %u, state: %u",
|
||||
dma_row_idx, row->state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (row->state == CAM_DMA_FENCE_STATE_ACTIVE) {
|
||||
CAM_WARN(CAM_DMA_FENCE,
|
||||
"Unsignaled fence being released name: %s seqno: %llu fd:%d",
|
||||
|
新しいイシューから参照
ユーザーをブロックする