From 8fdd3992f0b4d37b23c2cc645c95f7721b446671 Mon Sep 17 00:00:00 2001 From: Jean-Philippe Andre Date: Tue, 14 Jan 2014 13:33:16 +0900 Subject: [PATCH] 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 53581a4ce9..bc6c2d8ede 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 08268455eb..fbfc24e972 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); }