Fixed to prevent page fault via invalid address. 86/276086/3
authorJoonbum Ko <joonbum.ko@samsung.com>
Thu, 9 Jun 2022 10:04:11 +0000 (19:04 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Wed, 10 Aug 2022 05:00:46 +0000 (14:00 +0900)
 - If the last_enq_buffer of wl_egl_surface has a wrong pointer address,
  page fault may occur inside the tbm_surface_internal_is_valid of libtbm.
 - To prevent this problem, it is modified to check in advance from
  the list of buffers of wl_egl_surface.

Change-Id: I459b182e9ed435ce93a3a862251869fb9c7829ad
Signed-off-by: Joonbum Ko <joonbum.ko@samsung.com>
src/tpl_wl_egl_thread.c

index e94fe16..d4efca0 100755 (executable)
@@ -2445,35 +2445,37 @@ __tpl_wl_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns,
 
        TPL_OBJECT_UNLOCK(surface);
        tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
-       if (wl_egl_surface->reset == TPL_TRUE &&
-               tbm_surface_internal_is_valid(wl_egl_surface->last_enq_buffer)) {
-               tbm_surface_h last_enq_buffer = wl_egl_surface->last_enq_buffer;
-               tpl_wl_egl_buffer_t *enqueued_buffer =
-                       _get_wl_egl_buffer(last_enq_buffer);
-
-               if (enqueued_buffer) {
-                       tbm_surface_internal_ref(last_enq_buffer);
-                       tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
-                       tpl_gmutex_lock(&enqueued_buffer->mutex);
-                       while (enqueued_buffer->status >= ENQUEUED &&
-                                  enqueued_buffer->status < COMMITTED) {
-                               tpl_result_t wait_result;
-                               TPL_INFO("[DEQ_AFTER_RESET]",
-                                                "waiting for previous wl_egl_buffer(%p) commit",
-                                                enqueued_buffer);
-
-                               wait_result = tpl_cond_timed_wait(&enqueued_buffer->cond,
-                                                                                                 &enqueued_buffer->mutex,
-                                                                                                 200); /* 200ms */
-                               if (wait_result == TPL_ERROR_TIME_OUT) {
-                                       TPL_WARN("timeout occured waiting signaled. wl_egl_buffer(%p)",
+       if (wl_egl_surface->reset == TPL_TRUE) {
+               if (_check_buffer_validate(wl_egl_surface, wl_egl_surface->last_enq_buffer) &&
+                       tbm_surface_internal_is_valid(wl_egl_surface->last_enq_buffer)) {
+                       tbm_surface_h last_enq_buffer = wl_egl_surface->last_enq_buffer;
+                       tpl_wl_egl_buffer_t *enqueued_buffer =
+                               _get_wl_egl_buffer(last_enq_buffer);
+
+                       if (enqueued_buffer) {
+                               tbm_surface_internal_ref(last_enq_buffer);
+                               tpl_gmutex_unlock(&wl_egl_surface->surf_mutex);
+                               tpl_gmutex_lock(&enqueued_buffer->mutex);
+                               while (enqueued_buffer->status >= ENQUEUED &&
+                                          enqueued_buffer->status < COMMITTED) {
+                                       tpl_result_t wait_result;
+                                       TPL_INFO("[DEQ_AFTER_RESET]",
+                                                        "waiting for previous wl_egl_buffer(%p) commit",
                                                         enqueued_buffer);
-                                       break;
+
+                                       wait_result = tpl_cond_timed_wait(&enqueued_buffer->cond,
+                                                                                                         &enqueued_buffer->mutex,
+                                                                                                         200); /* 200ms */
+                                       if (wait_result == TPL_ERROR_TIME_OUT) {
+                                               TPL_WARN("timeout occured waiting signaled. wl_egl_buffer(%p)",
+                                                                enqueued_buffer);
+                                               break;
+                                       }
                                }
+                               tpl_gmutex_unlock(&enqueued_buffer->mutex);
+                               tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
+                               tbm_surface_internal_unref(last_enq_buffer);
                        }
-                       tpl_gmutex_unlock(&enqueued_buffer->mutex);
-                       tpl_gmutex_lock(&wl_egl_surface->surf_mutex);
-                       tbm_surface_internal_unref(last_enq_buffer);
                }
 
                wl_egl_surface->last_enq_buffer = NULL;