jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=8fdd3992f0b4d37b23c2cc645c95f7721b446671

commit 8fdd3992f0b4d37b23c2cc645c95f7721b446671
Author: Jean-Philippe Andre <[email protected]>
Date:   Tue Jan 14 13:33:16 2014 +0900

    Eio monitor: Fix crash on invalid data access
    
    Fix race condition when touching/changing a (theme) file often.
    An Eio_Monitor was marked as "delete_me" but the rename callback
    was still called, leading to memory access to already freed
    objects.
    
    Test protocol was:
    ELM_THEME=~/default.edj elementary_test &
    watch touch ~/default.edj
---
 src/lib/eio/eio_monitor.c         | 12 +++++++++++-
 src/lib/eio/eio_monitor_inotify.c | 12 +++++++++---
 2 files changed, 20 insertions(+), 4 deletions(-)

diff --git a/src/lib/eio/eio_monitor.c b/src/lib/eio/eio_monitor.c
index 53581a4..bc6c2d8 100644
--- a/src/lib/eio/eio_monitor.c
+++ b/src/lib/eio/eio_monitor.c
@@ -37,7 +37,11 @@ _eio_monitor_free(Eio_Monitor *monitor)
    if (!monitor->delete_me)
      eina_hash_del(_eio_monitors, monitor->path, monitor);
 
-   if (monitor->exist) eio_file_cancel(monitor->exist);
+   if (monitor->exist)
+     {
+        eio_file_cancel(monitor->exist);
+        monitor->exist = NULL;
+     }
 
    if (monitor->backend)
      {
@@ -185,6 +189,9 @@ _eio_monitor_send(Eio_Monitor *monitor, const char 
*filename, int event_code)
 {
    Eio_Monitor_Event *ev;
 
+   if (monitor->delete_me)
+     return;
+
    ev = calloc(1, sizeof (Eio_Monitor_Event));
    if (!ev) return;
 
@@ -200,6 +207,9 @@ _eio_monitor_rename(Eio_Monitor *monitor, const char 
*newpath)
 {
   const char *tmp;
 
+  if (monitor->delete_me)
+    return;
+
   /* destroy old state */
   if (monitor->exist)
     {
diff --git a/src/lib/eio/eio_monitor_inotify.c 
b/src/lib/eio/eio_monitor_inotify.c
index 0826845..fbfc24e 100644
--- a/src/lib/eio/eio_monitor_inotify.c
+++ b/src/lib/eio/eio_monitor_inotify.c
@@ -92,6 +92,9 @@ _eio_inotify_events(Eio_Monitor_Backend *backend, const char 
*file, int mask)
    unsigned int i;
    Eina_Bool is_dir;
 
+   if (backend->parent->delete_me)
+     return;
+
    length = file ? strlen(file) : 0;
    tmp_length = eina_stringshare_strlen(backend->parent->path) + length + 2;
    tmp = alloca(sizeof (char) * tmp_length);
@@ -255,13 +258,16 @@ void eio_monitor_backend_add(Eio_Monitor *monitor)
 
 void eio_monitor_backend_del(Eio_Monitor *monitor)
 {
+   Eio_Monitor_Backend *backend;
+
    if (!_inotify_fdh)
      eio_monitor_fallback_del(monitor);
 
-   if (!monitor->backend) return;
-
-   eina_hash_del(_inotify_monitors, &monitor->backend->hwnd, monitor->backend);
+   backend = monitor->backend;
    monitor->backend = NULL;
+   if (!backend) return;
+
+   eina_hash_del(_inotify_monitors, &backend->hwnd, backend);
 }
 
 

-- 


Reply via email to