Linux 커널에서는 다음 취약점이 해결되었습니다. 미디어: mediatek: vcodec: 인코더 릴리스 경로에서 use-after-free 수정 fops_vcodec_release() 함수는 컨텍스트 구조(ctx)를 해제합니다. ctx->encode_work에서 보류 중이거나 실행 중인 작업을 먼저 취소하지 않고 그러면 작업 대기열 처리기(mtk_venc_worker)가 실행되는 경주 창이 생성됩니다. 해제된 후에도 여전히 컨텍스트 메모리에 액세스하고 있을 수 있습니다. 경쟁 조건: CPU 0(릴리스 경로) CPU 1(작업 대기열)
Linux 커널에서는 다음 취약점이 해결되었습니다.
미디어: mediatek: vcodec: 인코더 릴리스 경로에서 use-after-free 수정
fops_vcodec_release() 함수는 컨텍스트 구조(ctx)를 해제합니다. ctx->encode_work에서 보류 중이거나 실행 중인 작업을 먼저 취소하지 않고 그러면 작업 대기열 처리기(mtk_venc_worker)가 실행되는 경주 창이 생성됩니다. 해제된 후에도 여전히 컨텍스트 메모리에 액세스하고 있을 수 있습니다.
경쟁 조건:
CPU 0(릴리스 경로) CPU 1(작업 대기열)
-------- ------------------
fops_vcodec_release()
v4l2_m2m_ctx_release()
v4l2_m2m_cancel_job()
// m2m 작업이 "완료"되기를 기다립니다.
mtk_venc_worker()
v4l2_m2m_job_finish()
// m2m 작업 "완료"
// 하지만 작업자는 여전히 실행 중입니다!
// 작업 완료 후 액세스:
다른 ctx 역참조
// ctx가 이미 해제된 경우 UAF
// 반환(작업 "완료")
kfree(ctx) // ctx가 해제되었습니다.
근본 원인: v4l2_m2m_ctx_release()는 m2m 작업만 기다립니다. 작업 대기열 수명 주기가 아닌 수명 주기(TRANS_RUNNING 플래그를 통해). v4l2_m2m_job_finish()가 호출된 후 m2m 프레임워크는 다음을 고려합니다. 작업이 완료되고 v4l2_m2m_ctx_release()가 반환되지만 작업자는 함수는 계속 실행되며 여전히 ctx에 액세스할 수 있습니다.
작업은 다음을 통해 인코딩 작업 중에 대기열에 추가됩니다. queue_work(ctx->dev->encode_workqueue, &ctx->encode_work) 작업자 함수는 ctx->m2m_ctx, ctx->dev 및 기타 ctx에 액세스합니다. v4l2_m2m_job_finish()를 호출한 후에도 필드가 표시됩니다.
이 취약점은 계측된 도구를 실행하여 KASAN에서 확인되었습니다. post-job_finish 경주 창을 넓히는 테스트 모듈입니다. KASAN이 감지했습니다:
버그: KASAN: mtk_venc_worker+0x159/0x180에서 slab-use-after-free kworker/u8:0/12 작업으로 addr ffff88800326e000에서 크기 4를 읽습니다.
작업 대기열: mtk_vcodec_enc_wq mtk_venc_worker
작업 47에 의해 할당됨: __kasan_kmalloc+0x7f/0x90 fops_vcodec_open+0x85/0x1a0
작업 47에 의해 해제됨: __kasan_slab_free+0x43/0x70 kfree+0xee/0x3a0 fops_vcodec_release+0xb7/0x190
kfree(ctx) 전에 cancel_work_sync(&ctx->encode_work)를 호출하여 이 문제를 해결하세요. 이렇게 하면 작업 대기열 처리기가 취소되고(보류 중인 경우) 동기화(실행 중인 핸들러가 완료될 때까지 대기) 컨텍스트가 해제됩니다.
배치 근거: 수정 사항은 v4l2_ctrl_handler_free() 이후에 배치됩니다. 그리고 list_del_init(&ctx->list) 앞에 있습니다. 이 시점에서 모든 m2m 작업은 완료되었습니다(v4l2_m2m_ctx_release()가 반환됨). 목록에서 ctx를 제거하기 전에 작업 대기열이 동기화되고 그것을 풀어줍니다.
참고: 열기 오류 경로에는 cancel_work_sync()가 필요하지 않습니다. INIT_WORK()는 작업 구조만 초기화하며 예약은 하지 않습니다. 그것. 작업은 나중에 device_run() 작업 중에만 예약됩니다.
왜 이 VPI인가 (설명가능 · 실험적)
VPI 산정 기준
| 영향도 | 78.00 |
| 악용 신호(추가 악용신호 없음) | ×1.00 |
| VPI | 78.00 |
VPI 공식 vpi-v1 기준