udevd: don't use monitor after manager_exit()
authorMartin Wilck <mwilck@suse.com>
Tue, 26 Nov 2019 17:39:09 +0000 (18:39 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 15 Dec 2019 11:15:39 +0000 (12:15 +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 testing the validity of manager->monitor in on_sigchld().

(cherry picked from commit 030f4571670537c76355c5d923468c9a61aa77e9)

src/udev/udevd.c

index cb5123042a2a5195f08c39b5a23f4b429230967c..3decb78c4a686ad36044f45983a37265c7644a49 100644 (file)
@@ -1335,10 +1335,12 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi
                         device_delete_db(worker->event->dev);
                         device_tag_index(worker->event->dev, NULL, false);
 
-                        /* forward kernel event without amending it */
-                        r = device_monitor_send_device(manager->monitor, NULL, worker->event->dev_kernel);
-                        if (r < 0)
-                                log_device_error_errno(worker->event->dev_kernel, r, "Failed to send back device to kernel: %m");
+                        if (manager->monitor) {
+                                /* forward kernel event without amending it */
+                                r = device_monitor_send_device(manager->monitor, NULL, worker->event->dev_kernel);
+                                if (r < 0)
+                                        log_device_error_errno(worker->event->dev_kernel, r, "Failed to send back device to kernel: %m");
+                        }
                 }
 
                 worker_free(worker);