ref clients during exe_inst deletion to avoid invalid access after free

in the case where clients are deleted during the same loop that they are
added to an exe_inst, the client will be destroyed before the instance's
delete event returns

ref T4963
This commit is contained in:
Mike Blumenkrantz 2017-02-10 17:23:43 -05:00
parent 3d3e5e67fb
commit 12655becaa
2 changed files with 6 additions and 3 deletions

View File

@ -618,11 +618,12 @@ _e_client_del(E_Client *ec)
else else
{ {
if (!ec->exe_inst->deleted) if (!ec->exe_inst->deleted)
ec->exe_inst->clients = eina_list_remove(ec->exe_inst->clients, ec); {
ec->exe_inst->clients = eina_list_remove(ec->exe_inst->clients, ec);
ec->exe_inst = NULL;
}
} }
} }
if (ec->exe_inst && (!ec->exe_inst->deleted))
ec->exe_inst = NULL;
_e_client_mouse_action_end(ec); _e_client_mouse_action_end(ec);
if (action_client == ec) _e_client_action_finish(); if (action_client == ec) _e_client_action_finish();

View File

@ -612,6 +612,7 @@ _e_exec_instance_free(E_Exec_Instance *inst)
{ {
inst->deleted = 1; inst->deleted = 1;
inst->ref++; inst->ref++;
E_LIST_FOREACH(inst->clients, e_object_ref);
ecore_event_add(E_EVENT_EXEC_DEL, inst, _e_exec_cb_exec_del_free, inst); ecore_event_add(E_EVENT_EXEC_DEL, inst, _e_exec_cb_exec_del_free, inst);
return EINA_FALSE; return EINA_FALSE;
} }
@ -622,6 +623,7 @@ _e_exec_instance_free(E_Exec_Instance *inst)
EINA_LIST_FREE(inst->clients, ec) EINA_LIST_FREE(inst->clients, ec)
{ {
ec->exe_inst = NULL; ec->exe_inst = NULL;
e_object_unref(E_OBJECT(ec));
} }
if (inst->desktop) efreet_desktop_free(inst->desktop); if (inst->desktop) efreet_desktop_free(inst->desktop);
if (!inst->phony) if (!inst->phony)