udevd: fix crash when workers time out after exit is signal caught
authorMartin Wilck <mwilck@suse.com>
Tue, 12 Nov 2019 15:43:42 +0000 (16:43 +0100)
committerMartin Wilck <mwilck@suse.com>
Tue, 12 Nov 2019 15:43:42 +0000 (16:43 +0100)
If udevd receives an exit signal, it releases its reference on the udev
monitor in manager_exit(). If at this time a worker is hanging, and if
the event timeout for this worker expires before udevd exits, udevd
crashes in on_sigchld()->udev_monitor_send_device(), because the monitor
has already been freed.

Fix this by releasing the main process's monitor ref later, in
manager_free().

src/udev/udevd.c

index 144a20e..2bb3227 100644 (file)
@@ -293,6 +293,8 @@ static void manager_free(Manager *manager) {
         if (!manager)
                 return;
 
+        manager->monitor = sd_device_monitor_unref(manager->monitor);
+
         udev_builtin_exit();
 
         if (manager->pid == getpid_cached())
@@ -789,8 +791,6 @@ static void manager_exit(Manager *manager) {
         manager->inotify_event = sd_event_source_unref(manager->inotify_event);
         manager->fd_inotify = safe_close(manager->fd_inotify);
 
-        manager->monitor = sd_device_monitor_unref(manager->monitor);
-
         /* discard queued events and kill workers */
         event_queue_cleanup(manager, EVENT_QUEUED);
         manager_kill_workers(manager);