Procházet zdrojové kódy

msm: camera: sync: Avoiding UAF on get dma fence

Two threads can access same dma fence, one to get_fence and other
to put_fence. Missing locks and checks on fence could lead to use
after free case. This change adds proper locks and checks before
dma fence get call to avoid this.

CRs-Fixed: 3782903
Change-Id: I283e87f09c44b57bed3dbb782113f3629c9a29bd
Signed-off-by: Yash Upadhyay <[email protected]>
Yash Upadhyay před 1 rokem
rodič
revize
96ff7cbcd8
1 změnil soubory, kde provedl 13 přidání a 0 odebrání
  1. 13 0
      drivers/cam_sync/cam_sync_dma_fence.c

+ 13 - 0
drivers/cam_sync/cam_sync_dma_fence.c

@@ -330,6 +330,7 @@ struct dma_fence *cam_dma_fence_get_fence_from_fd(
 	int32_t fd, int32_t *dma_fence_row_idx)
 {
 	struct dma_fence *dma_fence = NULL;
+	struct cam_dma_fence_row *row;
 
 	dma_fence = __cam_dma_fence_find_fence_in_table(fd, dma_fence_row_idx);
 	if (IS_ERR_OR_NULL(dma_fence)) {
@@ -339,7 +340,19 @@ struct dma_fence *cam_dma_fence_get_fence_from_fd(
 		return cam_dma_fence_get_fence_from_sync_file(fd, dma_fence_row_idx);
 	}
 
+	spin_lock_bh(&g_cam_dma_fence_dev->row_spinlocks[*dma_fence_row_idx]);
+	row = &g_cam_dma_fence_dev->rows[*dma_fence_row_idx];
+
+	if (row->state == CAM_DMA_FENCE_STATE_INVALID) {
+		CAM_ERR(CAM_DMA_FENCE,
+			"dma fence at idx: %d is in invalid state: %d",
+			dma_fence_row_idx, row->state);
+		spin_unlock_bh(&g_cam_dma_fence_dev->row_spinlocks[*dma_fence_row_idx]);
+		return ERR_PTR(-EINVAL);
+	}
+
 	dma_fence_get(dma_fence);
+	spin_unlock_bh(&g_cam_dma_fence_dev->row_spinlocks[*dma_fence_row_idx]);
 
 	CAM_DBG(CAM_DMA_FENCE, "dma fence found for fd: %d with seqno: %llu ref_cnt: %u",
 		fd, dma_fence->seqno, kref_read(&dma_fence->refcount));