]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev: refuse to enable inotify watch on remove event
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 6 Mar 2021 11:45:17 +0000 (20:45 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 30 Apr 2021 10:21:18 +0000 (19:21 +0900)
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
src/udev/udev-event.h
src/udev/udevd.c

index 2e82be6fb39ad6e90ebe7badaf0e8941e47bedec..f4dbcef95980bf0219d980913f09a2d9787ed8a8 100644 (file)
@@ -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;
+}
index d90cc10a2d8a67018b56aaa022553f11e5474dc1..2067909fde4c61391620b0f54462b7df216d1d4d 100644 (file)
@@ -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);
index 299f89566f57395e736bdeac6f08cd4169e718cd..9689e15b1c45999cba6b9cfc8b6db7e7c3fb5e85 100644 (file)
@@ -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;