udevd: close race in udev settle

Signed-off-by: Anthony G. Basile <blueness@gentoo.org>
This commit is contained in:
Tom Gundersen 2015-03-18 19:13:22 -04:00 committed by Anthony G. Basile
parent a46b4ff7cc
commit 3fa57f4051

View File

@ -292,7 +292,7 @@ static void worker_new(struct event *event) {
fd_lock = open(udev_device_get_devnode(d), O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NONBLOCK);
if (fd_lock >= 0 && flock(fd_lock, LOCK_SH|LOCK_NB) < 0) {
log_debug_errno(errno, "Unable to flock(%s), skipping event handling: %m", udev_device_get_devnode(d));
err = -EWOULDBLOCK;
err = -EAGAIN;
fd_lock = safe_close(fd_lock);
goto skip;
}
@ -899,6 +899,17 @@ static void handle_signal(struct udev *udev, int signo) {
}
}
static void event_queue_update(void) {
if (!udev_list_node_is_empty(&event_list)) {
int fd;
fd = open("/run/udev/queue", O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
if (fd >= 0)
close(fd);
} else
unlink("/run/udev/queue");
}
/*
* read the kernel command line, in case we need to get into debug mode
* udev.log-priority=<level> syslog priority
@ -1312,15 +1323,7 @@ int main(int argc, char *argv[]) {
}
/* tell settle that we are busy or idle */
if (!udev_list_node_is_empty(&event_list)) {
int fd;
fd = open("/run/udev/queue", O_WRONLY|O_CREAT|O_CLOEXEC|O_TRUNC|O_NOFOLLOW, 0444);
if (fd >= 0)
close(fd);
} else {
unlink("/run/udev/queue");
}
event_queue_update();
fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), timeout);
if (fdcount < 0)
@ -1445,6 +1448,11 @@ int main(int argc, char *argv[]) {
if (is_inotify)
handle_inotify(udev);
/* tell settle that we are busy or idle, this needs to be before the
* PING handling
*/
event_queue_update();
/*
* This needs to be after the inotify handling, to make sure,
* that the ping is send back after the possibly generated