From 0d77bc4a18efa21022fe90cf8d6051a7b5b039f3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 6 Mar 2021 20:45:17 +0900 Subject: [PATCH] udev: refuse to enable inotify watch on remove event Some udev rule may erroneously set inotify watch on remove event. For safety, silently ignore such an inotify watch enablement. This also moves inotify watch enablement code to udev-event.c. --- src/udev/udev-event.c | 31 +++++++++++++++++++++++++++++++ src/udev/udev-event.h | 1 + src/udev/udevd.c | 11 +++-------- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 2e82be6fb39..f4dbcef9598 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -1082,3 +1082,34 @@ void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec, int timeout_s } } } + +int udev_event_process_inotify_watch(UdevEvent *event, int inotify_fd) { + sd_device *dev; + int r; + + assert(event); + assert(inotify_fd >= 0); + + dev = event->dev; + + assert(dev); + + if (device_for_action(dev, SD_DEVICE_REMOVE)) + return 0; + + if (sd_device_get_devname(dev, NULL) < 0) + return 0; + + if (!event->inotify_watch) { + (void) udev_watch_end(inotify_fd, dev); + return 0; + } + + (void) udev_watch_begin(inotify_fd, dev); + + r = device_update_db(dev); + if (r < 0) + return log_device_debug_errno(dev, r, "Failed to update database under /run/udev/data/: %m"); + + return 0; +} diff --git a/src/udev/udev-event.h b/src/udev/udev-event.h index d90cc10a2d8..2067909fde4 100644 --- a/src/udev/udev-event.h +++ b/src/udev/udev-event.h @@ -74,6 +74,7 @@ int udev_event_execute_rules( Hashmap *properties_list, UdevRules *rules); void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec, int timeout_signal); +int udev_event_process_inotify_watch(UdevEvent *event, int inotify_fd); static inline usec_t udev_warn_timeout(usec_t timeout_usec) { return DIV_ROUND_UP(timeout_usec, 3); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 299f89566f5..9689e15b1c4 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -502,14 +502,9 @@ static int worker_process_device(Manager *manager, sd_device *dev) { /* in case rtnl was initialized */ manager->rtnl = sd_netlink_ref(udev_event->rtnl); - /* apply/restore/end inotify watch */ - if (udev_event->inotify_watch) { - (void) udev_watch_begin(manager->inotify_fd, dev); - r = device_update_db(dev); - if (r < 0) - return log_device_debug_errno(dev, r, "Failed to update database under /run/udev/data/: %m"); - } else - (void) udev_watch_end(manager->inotify_fd, dev); + r = udev_event_process_inotify_watch(udev_event, manager->inotify_fd); + if (r < 0) + return r; log_device_uevent(dev, "Device processed"); return 0; -- 2.47.3