hwc: fix use after free when tdm_hwc_set_vblank is enabled 73/293173/2
authorChangyeon Lee <cyeon.lee@samsung.com>
Mon, 22 May 2023 04:45:50 +0000 (13:45 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Mon, 22 May 2023 05:57:33 +0000 (14:57 +0900)
if hwc commit handler is called after vblank handler of
hwc commit is called, data of hwc_commit_handler is used
after it is freed because data of hwc_commit_handler is
freed in vblank handler.

this patch makes data of hwc_commit_handler is not used
to user_data of tdm_hwc_commit when tdm_hwc_set_vblank
is enabled.

Change-Id: Ib5445e2a012906d2c2941adaa674a11b9be3b5f0

src/tdm_hwc.c

index 185ee6a..81fb042 100644 (file)
@@ -176,9 +176,6 @@ _tdm_hwc_cb_commit(tdm_hwc *hwc_backend, unsigned int sequence,
        tdm_thread_cb_hwc_commit hwc_commit;
        tdm_error ret;
 
-       if (hwc_commit_handler && hwc_commit_handler->use_vblank)
-               return;
-
        if (hwc_commit_handler)
                private_hwc = hwc_commit_handler->private_hwc;
        else
@@ -207,9 +204,6 @@ _tdm_hwc_cb_commit_hal_tdm(hal_tdm_hwc *hwc_backend, unsigned int sequence,
        tdm_thread_cb_hwc_commit hwc_commit;
        tdm_error ret;
 
-       if (hwc_commit_handler && hwc_commit_handler->use_vblank)
-               return;
-
        if (hwc_commit_handler)
                private_hwc = hwc_commit_handler->private_hwc;
        else
@@ -925,8 +919,6 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d
        hwc_commit_handler->func = func;
        hwc_commit_handler->user_data = user_data;
        hwc_commit_handler->owner_tid = syscall(SYS_gettid);
-       if (hwc_use_vblank)
-               hwc_commit_handler->use_vblank = 1;
 
        if (private_module == private_display->virtual_module) {
                private_voutput = private_output->private_voutput;
@@ -937,14 +929,16 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d
                }
        }
 
-       if (private_module->use_hal_tdm)
-               ret = (tdm_error)hal_tdm_hwc_commit((hal_tdm_hwc *)private_hwc->hwc_backend, sync, hwc_commit_handler);
-       else
-               ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, hwc_commit_handler);
-       TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
-
        if (hwc_use_vblank) {
                /* LCOV_EXCL_START */
+               hwc_commit_handler->use_vblank = 1;
+
+               if (private_module->use_hal_tdm)
+                       ret = (tdm_error)hal_tdm_hwc_commit((hal_tdm_hwc *)private_hwc->hwc_backend, sync, NULL);
+               else
+                       ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, NULL);
+               TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
+
                ret = _tdm_hwc_vblank(private_hwc, hwc_commit_handler);
                if (ret == TDM_ERROR_NONE) {
                        if (tdm_debug_module & TDM_DEBUG_COMMIT)
@@ -954,6 +948,12 @@ tdm_hwc_commit(tdm_hwc *hwc, int sync, tdm_hwc_commit_handler func, void *user_d
                        goto commit_failed;
                /* LCOV_EXCL_STOP */
        } else {
+               if (private_module->use_hal_tdm)
+                       ret = (tdm_error)hal_tdm_hwc_commit((hal_tdm_hwc *)private_hwc->hwc_backend, sync, hwc_commit_handler);
+               else
+                       ret = func_hwc->hwc_commit(private_hwc->hwc_backend, sync, hwc_commit_handler);
+               TDM_GOTO_IF_FAIL(ret == TDM_ERROR_NONE, commit_failed);
+
                if (tdm_debug_module & TDM_DEBUG_COMMIT)
                        TDM_INFO("hwc(%d) backend commit: handle(%p) func(%p) user_data(%p)",
                                        private_hwc->index, hwc_commit_handler, func, user_data);