VirtGL: Fix Bug N_SE-43071.
authorFrédéric Dalleau <frederic.dalleau@linux.intel.com>
Thu, 11 Jul 2013 15:40:07 +0000 (17:40 +0200)
committerKitae Kim <kt920.kim@samsung.com>
Tue, 16 Jul 2013 10:52:20 +0000 (19:52 +0900)
Reproduction scenario is :
CreatePixmap
CreateContext 1
CreateContext 2
MakeCurrent 1, Pixmap
MakeCurrent NULL, NULL
MakeCurrent 2, Pixmap => Segmentation fault in unbind_qsurface.
Pixmap has a dangling pointer to context 1 that has been destroyed.

tizen/src/hw/opengl_exec.c

index 831eac7e76e520afb06f3997bc8b5a373cbb7cfe..0fee10ce713d489dfdfd80ffd52a8ad2d2cdfe23 100644 (file)
@@ -607,6 +607,7 @@ static inline ClientGLXDrawable to_drawable(arg_t arg)
 static void bind_qsurface(GLState *state,
                           QGloSurface *qsurface)
 {
+    DEBUGF("%s qsurface %p qsurface->glstate %p new state %p\n", __FUNCTION__, qsurface, qsurface->glstate, state);
     qsurface->glstate = state;
 
        if ( qsurface->type == SURFACE_WINDOW )
@@ -619,6 +620,12 @@ static void bind_qsurface(GLState *state,
 static void unbind_qsurface(GLState *state,
                           QGloSurface *qsurface)
 {
+    if (!state || !qsurface) {
+        DEBUGF("%s invalid parameter, state %p, qsurface %p\n", __FUNCTION__, state, qsurface);
+        return;
+    }
+
+    DEBUGF("%s qsurface %p qsurface->glstate %p old state %p\n", __FUNCTION__, qsurface, qsurface->glstate, state);
     qsurface->glstate = NULL;
 
        if ( qsurface->type == SURFACE_WINDOW )
@@ -977,6 +984,8 @@ static void destroy_gl_state(GLState *state)
 
     QGloSurface *qsurface, *tmp;
 
+    DEBUGF("%s state %p\n", __FUNCTION__, state);
+
     QTAILQ_FOREACH_SAFE(qsurface, &state->qsurfaces, next, tmp) {
         glo_surface_destroy(qsurface->surface);
         QTAILQ_REMOVE(&state->qsurfaces, qsurface, next);
@@ -1590,6 +1599,8 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args
                 int fake_ctxt = process->next_available_context_number;
                 ret.i = fake_ctxt;
 
+                DEBUGF( "fake_ctxt = %d\n", fake_ctxt);
+
                 GLState *state = _create_context(process, fake_ctxt, fake_shareList);
                 state->context = glo_context_create(fbconfig->formatFlags,
                                                     shareListState?shareListState->context:0); // FIXME GW get from fbconfig
@@ -1644,7 +1655,7 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args
                                 process->glstates[i]->ref--;
                                 if (process->glstates[i]->ref == 0) {
                                     DEBUGF(
-                                            "destroy_gl_state fake_ctxt = %d\n",
+                                            "destroy_gl_state fake_sharelist fake_ctxt = %d\n",
                                             process->glstates[i]->
                                             fake_ctxt);
                                     destroy_gl_state(process->
@@ -1712,15 +1723,19 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args
             int fake_ctxt = (int) args[2];
             GLState *glstate = NULL;
 
-//            DEBUGF( "Makecurrent: fake_ctx=%d client_drawable=%08x\n", fake_ctxt, client_drawable);
+            DEBUGF( "Makecurrent: fake_ctx=%d client_drawable=%08x\n", fake_ctxt, client_drawable);
 
             if (client_drawable == 0 && fake_ctxt == 0) {
                 /* Release context */
-                if(process->current_state->current_qsurface)
-                    process->current_state->current_qsurface->ref--;
+                if(process->current_state->current_qsurface) {
+                    if(process->current_state->current_qsurface->type != SURFACE_PIXMAP)
+                        process->current_state->current_qsurface->ref--;
+                    else
+                        unbind_qsurface(process->current_state, process->current_state->current_qsurface);
+                }
                 process->current_state = &process->default_state;
 
-//                DEBUGF( " --release\n");
+                DEBUGF( " --release\n");
                 glo_surface_makecurrent(0);
             } else { /* Lookup GLState struct for this context */
                 glstate = get_glstate_for_fake_ctxt(process, fake_ctxt);
@@ -1739,11 +1754,11 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args
                                           qsurface->status = SURFACE_ACTIVE;
 
                        bind_qsurface(glstate, qsurface);
-//                       DEBUGF( " --Client drawable not found, create new surface: %16x %16lx\n", (unsigned int)qsurface, (unsigned long int)client_drawable);
+                       DEBUGF( " --Client drawable not found, create new surface: %16x %16lx\n", (unsigned int)qsurface, (unsigned long int)client_drawable);
 
                     }
                     else {
-//                       DEBUGF( " --Client drawable found, using surface: %16x %16lx\n", (unsigned int)glstate->current_qsurface, (unsigned long int)client_drawable);
+                       DEBUGF( " --Client drawable found, using surface: %16x %16lx\n", (unsigned int)glstate->current_qsurface, (unsigned long int)client_drawable);
                     }
 #if 0
                     /*Test old surface contents */