]> git.ipfire.org Git - thirdparty/snapper.git/commitdiff
- fixed segmentation fault with DBus (bnc#860119) 48/head
authorArvin Schnell <aschnell@suse.de>
Thu, 20 Feb 2014 14:16:47 +0000 (15:16 +0100)
committerArvin Schnell <aschnell@suse.de>
Thu, 20 Feb 2014 14:16:47 +0000 (15:16 +0100)
dbus/DBusMainLoop.cc
dbus/DBusMainLoop.h
package/snapper.changes

index f7e45611b734011466435259f30e0dc7475ad1b6..cd63d2595c84076a598134aedae2950f29cb2280 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Novell, Inc.
+ * Copyright (c) [2012-2014] Novell, Inc.
  *
  * All Rights Reserved.
  *
 namespace DBus
 {
 
+    MainLoop::Watch::Watch(DBusWatch* dbus_watch)
+       : dbus_watch(dbus_watch), enabled(false), fd(-1), events(0)
+    {
+       enabled = dbus_watch_get_enabled(dbus_watch);
+       fd = dbus_watch_get_unix_fd(dbus_watch);
+
+       unsigned int flags = dbus_watch_get_flags(dbus_watch);
+       if (flags & DBUS_WATCH_READABLE)
+           events |= POLLIN;
+       if (flags & DBUS_WATCH_WRITABLE)
+           events |= POLLOUT;
+    }
+
+
+    MainLoop::Timeout::Timeout(DBusTimeout* dbus_timeout)
+       : dbus_timeout(dbus_timeout), enabled(false), interval(0)
+    {
+       enabled = dbus_timeout_get_enabled(dbus_timeout);
+       interval = dbus_timeout_get_interval(dbus_timeout);
+    }
+
+
     MainLoop::MainLoop(DBusBusType type)
        : Connection(type), idle_timeout(-1)
     {
@@ -100,36 +122,37 @@ namespace DBus
 
            periodic();
 
-           for (vector<struct pollfd>::const_iterator it2 = pollfds.begin(); it2 != pollfds.end(); ++it2)
+           for (vector<struct pollfd>::const_iterator it1 = pollfds.begin(); it1 != pollfds.end(); ++it1)
            {
-               if (it2->fd == wakeup_pipe[0] && (it2->revents & POLLIN))
+               if (it1->fd == wakeup_pipe[0])
                {
-                   char arbitrary;
-                   read(wakeup_pipe[0], &arbitrary, 1);
+                   if (it1->revents & POLLIN)
+                   {
+                       char arbitrary;
+                       read(wakeup_pipe[0], &arbitrary, 1);
+                   }
                }
-           }
-
-           for (vector<Watch>::const_iterator it = watches.begin(); it != watches.end(); ++it)
-           {
-               if (it->enabled)
+               else
                {
-                   for (vector<struct pollfd>::const_iterator it2 = pollfds.begin(); it2 != pollfds.end(); ++it2)
-                   {
-                       if (it2->fd == it->fd)
-                       {
-                           unsigned int flags = 0;
+                   unsigned int flags = 0;
 
-                           if (it2->revents & POLLIN)
-                               flags |= DBUS_WATCH_READABLE;
+                   if (it1->revents & POLLIN)
+                       flags |= DBUS_WATCH_READABLE;
 
-                           if (it2->revents & POLLOUT)
-                               flags |= DBUS_WATCH_WRITABLE;
+                   if (it1->revents & POLLOUT)
+                       flags |= DBUS_WATCH_WRITABLE;
 
-                           if (flags != 0)
-                           {
-                               boost::lock_guard<boost::mutex> lock(mutex);
-                               dbus_watch_handle(it->dbus_watch, flags);
-                           }
+                   if (flags != 0)
+                   {
+                       // Do not iterate over watches here since calling dbus_watch_handle() can
+                       // trigger a remove_watch() callback, thus invalidating the iterator.
+                       // Instead always search for the watch.
+
+                       vector<Watch>::const_iterator it2 = find_enabled_watch(it1->fd, it1->events);
+                       if (it2 != watches.end())
+                       {
+                           boost::lock_guard<boost::mutex> lock(mutex);
+                           dbus_watch_handle(it2->dbus_watch, flags);
                        }
                    }
                }
@@ -178,6 +201,17 @@ namespace DBus
     }
 
 
+    vector<MainLoop::Watch>::iterator
+    MainLoop::find_enabled_watch(int fd, int events)
+    {
+       for (vector<Watch>::iterator it = watches.begin(); it != watches.end(); ++it)
+           if (it->enabled && it->fd == fd && it->events == events)
+               return it;
+
+       return watches.end();
+    }
+
+
     vector<MainLoop::Timeout>::iterator
     MainLoop::find_timeout(DBusTimeout* dbus_timeout)
     {
@@ -192,22 +226,9 @@ namespace DBus
     dbus_bool_t
     MainLoop::add_watch(DBusWatch* dbus_watch, void* data)
     {
-       Watch tmp;
-       tmp.enabled = dbus_watch_get_enabled(dbus_watch);
-       tmp.fd = dbus_watch_get_unix_fd(dbus_watch);
-       tmp.flags = dbus_watch_get_flags(dbus_watch);
-
-       tmp.events = 0;
-       if (tmp.flags & DBUS_WATCH_READABLE)
-           tmp.events |= POLLIN;
-       if (tmp.flags & DBUS_WATCH_WRITABLE)
-           tmp.events |= POLLOUT;
-
-       tmp.dbus_watch = dbus_watch;
-
+       Watch tmp(dbus_watch);
        MainLoop* s = static_cast<MainLoop*>(data);
        s->watches.push_back(tmp);
-
        return true;
     }
 
@@ -233,14 +254,9 @@ namespace DBus
     dbus_bool_t
     MainLoop::add_timeout(DBusTimeout* dbus_timeout, void* data)
     {
-       Timeout tmp;
-       tmp.enabled = dbus_timeout_get_enabled(dbus_timeout);
-       tmp.interval = dbus_timeout_get_interval(dbus_timeout);
-       tmp.dbus_timeout = dbus_timeout;
-
+       Timeout tmp(dbus_timeout);
        MainLoop* s = static_cast<MainLoop*>(data);
        s->timeouts.push_back(tmp);
-
        return true;
     }
 
@@ -249,7 +265,6 @@ namespace DBus
     MainLoop::remove_timeout(DBusTimeout* dbus_timeout, void* data)
     {
        MainLoop* s = static_cast<MainLoop*>(data);
-
        vector<Timeout>::iterator it = s->find_timeout(dbus_timeout);
        s->timeouts.erase(it);
     }
index ecf7717f6cd4df841eabc864db0da12b86d3076b..5ce66f0840920a79c2d380086fe2ca5ffec2de3b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Novell, Inc.
+ * Copyright (c) [2012-2014] Novell, Inc.
  *
  * All Rights Reserved.
  *
@@ -57,18 +57,21 @@ namespace DBus
 
        struct Watch
        {
+           Watch(DBusWatch* dbus_watch);
+
+           DBusWatch* dbus_watch;
            bool enabled;
            int fd;
-           unsigned int flags;
            int events;
-           DBusWatch* dbus_watch;
        };
 
        struct Timeout
        {
+           Timeout(DBusTimeout* dbus_timeout);
+
+           DBusTimeout* dbus_timeout;
            bool enabled;
            int interval;
-           DBusTimeout* dbus_timeout;
        };
 
        vector<Watch> watches;
@@ -76,6 +79,7 @@ namespace DBus
        int wakeup_pipe[2];
 
        vector<Watch>::iterator find_watch(DBusWatch* dbus_watch);
+       vector<Watch>::iterator find_enabled_watch(int fd, int events);
        vector<Timeout>::iterator find_timeout(DBusTimeout* dbus_timeout);
 
        static dbus_bool_t add_watch(DBusWatch* dbus_watch, void* data);
index 2ce2bb8151de5f7bf11c56533591308978d1510e..423b483276eab09af3a877d499fbe322d4c9a071 100644 (file)
@@ -1,3 +1,8 @@
+-------------------------------------------------------------------
+Thu Feb 20 15:04:30 CET 2014 - aschnell@suse.de
+
+- fixed segmentation fault with DBus (bnc#860119)
+
 -------------------------------------------------------------------
 Thu Feb 20 14:18:01 CET 2014 - aschnell@suse.de