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.
This commit is contained in:
Yu Watanabe
2021-03-06 20:45:17 +09:00
parent 4cac2260c8
commit 0d77bc4a18
3 changed files with 35 additions and 8 deletions

View 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;
}

View 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);

View 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;