common: don't allow mark_deleted corrupt the pending deleted list.
authorKrisztian Litkey <krisztian.litkey@intel.com>
Thu, 16 Jan 2014 12:59:36 +0000 (14:59 +0200)
committerKrisztian Litkey <krisztian.litkey@intel.com>
Thu, 16 Jan 2014 13:23:42 +0000 (15:23 +0200)
Make sure mark_deleted is not called twice for timer, deferred,
or wakeup objects to prevent it from corrupting the list of
pending deleted objects. The corruption itself is the result
of the same object being linked twice to the pending list and
consequently free'd twice. The other types of objects were
correctly protected against this.

The 'safeguard' is just check that the object had not been deleted
before calling mark_deleted. It would be safer to add this check to
mark_deleted itself but since the check is usually needed to protect
other things as well it is now done always by the caller.

src/common/mainloop.c

index 16e1f1b..32f8a1d 100644 (file)
@@ -709,7 +709,7 @@ void mrp_del_timer(mrp_timer_t *t)
      *        dispatch_timers().
      */
 
-    if (t != NULL) {
+    if (t != NULL && !is_deleted(t)) {
         mrp_debug("marking timer %p deleted", t);
 
         mark_deleted(t);
@@ -761,7 +761,7 @@ void mrp_del_deferred(mrp_deferred_t *d)
      *        in the dispatching loop.
      */
 
-    if (d != NULL) {
+    if (d != NULL && !is_deleted(d)) {
         mrp_debug("marking deferred %p deleted", d);
         mark_deleted(d);
     }
@@ -903,13 +903,11 @@ static void recalc_sigmask(mrp_mainloop_t *ml)
 
 void mrp_del_sighandler(mrp_sighandler_t *h)
 {
-    if (h != NULL) {
-        if (!is_deleted(h)) {
-            mrp_debug("marking sighandler %p deleted", h);
+    if (h != NULL && !is_deleted(h)) {
+        mrp_debug("marking sighandler %p deleted", h);
 
-            mark_deleted(h);
-            recalc_sigmask(h->ml);
-        }
+        mark_deleted(h);
+        recalc_sigmask(h->ml);
     }
 }
 
@@ -1006,7 +1004,7 @@ void mrp_del_wakeup(mrp_wakeup_t *w)
      *        in the dispatching loop.
      */
 
-    if (w != NULL) {
+    if (w != NULL && !is_deleted(w)) {
         mrp_debug("marking wakeup %p deleted", w);
         mark_deleted(w);
     }