Hi,

I believe I understand the bug now.

At heart this is indeed a race condition between the removing of the
seat due to the dbus name owner change (the path in the stacktrace)
and due to the IN_IGNORED event from inotify.

When a session is closed it will trigger the dbus event, which will remove
the watch, and call inotify_rm_watch. This may stop the inotify event from
coming. There is also a point where inotify events for paths that aren't
watched are filtered out (the reason why it doesn't cause an infinite loop),
so if the watch is removed before the inotify event hits that point it will
also be ok.

If however the inotify event arrives early enough that it makes it past this
then it will cause the watch to be removed as well.

The remove code does

           g_hash_table_remove (monitor->priv->path_to_watch,
                             watch->path);

which will crash if watch->path is NULL (I was wrong in my last comment,
as this uses a g_str_hash, not a g_direct_hash). It then calls

           monitor_release_watch (monitor, watch);

which does

           g_free (watch->path);
           watch->path = NULL;

so if one remove call makes it to that point before the other makes it
to the g_hash_table_remove call then it will cause the crash.

We can check for this before calling g_hash_table_remove, which makes
the time when it is possible to trigger the bug very short, but it's still
possible, so we should look for a better solution.

I think having the two threads do the removal is going to be problematic,
so we should push the removal from the inotify thread in to the main
thread. It can then check whether it has been removed yet without
being racy.

Thanks,

James

-- 
console-kit-daemon crashed with SIGSEGV in g_str_hash()
https://bugs.launchpad.net/bugs/269651
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.

-- 
ubuntu-bugs mailing list
ubuntu-bugs@lists.ubuntu.com
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to