summaryrefslogtreecommitdiffstats
path: root/src/udev
diff options
context:
space:
mode:
authorMartin Wilck <mwilck@suse.com>2019-11-26 18:39:09 +0100
committerMartin Wilck <mwilck@suse.com>2019-11-26 20:38:28 +0100
commit030f4571670537c76355c5d923468c9a61aa77e9 (patch)
tree4afacbf8d11912cded1bc0be616a3bd162b32de8 /src/udev
parentRevert "udevd: fix crash when workers time out after exit is signal caught" (diff)
downloadsystemd-030f4571670537c76355c5d923468c9a61aa77e9.tar.xz
systemd-030f4571670537c76355c5d923468c9a61aa77e9.zip
udevd: don't use monitor after manager_exit()
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().
Diffstat (limited to 'src/udev')
-rw-r--r--src/udev/udevd.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 144a20ec63..7678331897 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -1311,10 +1311,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);