diff options
author | Martin Wilck <mwilck@suse.com> | 2019-11-26 18:39:09 +0100 |
---|---|---|
committer | Martin Wilck <mwilck@suse.com> | 2019-11-26 20:38:28 +0100 |
commit | 030f4571670537c76355c5d923468c9a61aa77e9 (patch) | |
tree | 4afacbf8d11912cded1bc0be616a3bd162b32de8 /src/udev | |
parent | Revert "udevd: fix crash when workers time out after exit is signal caught" (diff) | |
download | systemd-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.c | 10 |
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); |