summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric Bail <cedric@osg.samsung.com>2016-05-05 21:55:43 -0700
committerCedric Bail <cedric@osg.samsung.com>2016-05-05 21:55:43 -0700
commitc7d652ade119116677b2c920cf936ea9572c12b0 (patch)
tree928286e5edc432b235b16e7a1b6937172050ad15
parentbfc19893d73d5ca8baf2e9df35183b6852d9e9e0 (diff)
ecore: fix legacy use of double free scenario.
-rw-r--r--src/lib/ecore/ecore_timer.c38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c
index 54cf773149..5be10520ea 100644
--- a/src/lib/ecore/ecore_timer.c
+++ b/src/lib/ecore/ecore_timer.c
@@ -147,23 +147,40 @@ typedef struct _Ecore_Timer_Legacy Ecore_Timer_Legacy;
147struct _Ecore_Timer_Legacy 147struct _Ecore_Timer_Legacy
148{ 148{
149 Ecore_Task_Cb func; 149 Ecore_Task_Cb func;
150
150 const void *data; 151 const void *data;
152
153 Eina_Bool inside_call : 1;
154 Eina_Bool delete_me : 1;
151}; 155};
152 156
153static Eina_Bool 157static Eina_Bool
158_ecore_timer_legacy_del(void *data, const Eo_Event *event EINA_UNUSED)
159{
160 Ecore_Timer_Legacy *legacy = data;
161
162 free(legacy);
163
164 return EO_CALLBACK_CONTINUE;
165}
166
167static Eina_Bool
154_ecore_timer_legacy_tick(void *data, const Eo_Event *event) 168_ecore_timer_legacy_tick(void *data, const Eo_Event *event)
155{ 169{
156 Ecore_Timer_Legacy *legacy = data; 170 Ecore_Timer_Legacy *legacy = data;
157 171
158 if (!_ecore_call_task_cb(legacy->func, (void*)legacy->data)) 172 legacy->inside_call = 1;
159 { 173 if (!_ecore_call_task_cb(legacy->func, (void*)legacy->data) ||
160 eo_del(event->obj); 174 legacy->delete_me)
161 free(legacy); 175 eo_del(event->obj);
162 }
163 176
164 return EO_CALLBACK_CONTINUE; 177 return EO_CALLBACK_CONTINUE;
165} 178}
166 179
180EO_CALLBACKS_ARRAY_DEFINE(legacy_timer,
181 { EFL_TIMER_EVENT_TICK, _ecore_timer_legacy_tick },
182 { EO_BASE_EVENT_DEL, _ecore_timer_legacy_del });
183
167EAPI Ecore_Timer * 184EAPI Ecore_Timer *
168ecore_timer_add(double in, 185ecore_timer_add(double in,
169 Ecore_Task_Cb func, 186 Ecore_Task_Cb func,
@@ -178,7 +195,7 @@ ecore_timer_add(double in,
178 legacy->func = func; 195 legacy->func = func;
179 legacy->data = data; 196 legacy->data = data;
180 timer = eo_add(MY_CLASS, ecore_main_loop_get(), 197 timer = eo_add(MY_CLASS, ecore_main_loop_get(),
181 eo_event_callback_add(eo_self, EFL_TIMER_EVENT_TICK, _ecore_timer_legacy_tick, legacy), 198 eo_event_callback_array_add(eo_self, legacy_timer(), legacy),
182 eo_key_data_set(eo_self, "_legacy", legacy), 199 eo_key_data_set(eo_self, "_legacy", legacy),
183 efl_timer_interval_set(eo_self, in)); 200 efl_timer_interval_set(eo_self, in));
184 201
@@ -199,7 +216,7 @@ ecore_timer_loop_add(double in,
199 legacy->func = func; 216 legacy->func = func;
200 legacy->data = data; 217 legacy->data = data;
201 timer = eo_add(MY_CLASS, ecore_main_loop_get(), 218 timer = eo_add(MY_CLASS, ecore_main_loop_get(),
202 eo_event_callback_add(eo_self, EFL_TIMER_EVENT_TICK, _ecore_timer_legacy_tick, legacy), 219 eo_event_callback_array_add(eo_self, legacy_timer(), legacy),
203 eo_key_data_set(eo_self, "_legacy", legacy), 220 eo_key_data_set(eo_self, "_legacy", legacy),
204 efl_timer_loop_reset(eo_self), 221 efl_timer_loop_reset(eo_self),
205 efl_timer_interval_set(eo_self, in)); 222 efl_timer_interval_set(eo_self, in));
@@ -219,9 +236,10 @@ ecore_timer_del(Ecore_Timer *timer)
219 legacy = eo_key_data_get(timer, "_legacy"); 236 legacy = eo_key_data_get(timer, "_legacy");
220 data = (void*) legacy->data; 237 data = (void*) legacy->data;
221 238
222 free(legacy); 239 if (legacy->inside_call)
223 eo_key_del(timer, "_legacy"); 240 legacy->delete_me = EINA_TRUE;
224 eo_del(timer); 241 else
242 eo_del(timer);
225 243
226 return data; 244 return data;
227} 245}