1
0
mirror of https://github.com/systemd/systemd synced 2025-10-05 19:54:46 +02:00

Compare commits

...

3 Commits

Author SHA1 Message Date
Mike Yuan
a00078e8c8
sd-event: fix infinite loop in inotify event handling (#38268)
Fixes #38265.
2025-07-21 10:14:58 +02:00
Yu Watanabe
b92258eb22 test: add test case for issue #38265 2025-07-20 02:18:03 +09:00
Yu Watanabe
064b9b2bb3 sd-event: drop inotify event from buffer when no event source is triggered
Even when we receive an inotify event, there is no relevant event source
exists. In that case, we need to drop the event from the buffer,
otherwise we cannot escape from the loop.

Fixes #38265.
2025-07-20 02:14:44 +09:00
2 changed files with 38 additions and 1 deletions

View File

@ -3955,9 +3955,12 @@ static int event_inotify_data_process(sd_event *e, InotifyData *d) {
}
}
/* Something pending now? If so, let's finish, otherwise let's read more. */
/* Something pending now? If so, let's finish. */
if (d->n_pending > 0)
return 1;
/* otherwise, drop the event and let's read more */
event_inotify_data_drop(e, d, sz);
}
return 0;

View File

@ -806,6 +806,40 @@ TEST(inotify_process_buffered_data) {
assert_se(sd_event_wait(e, 0) == 0);
}
static int inotify_handler_issue_38265(sd_event_source *s, const struct inotify_event *event, void *userdata) {
log_debug("Inotify event: mask=0x%x name=%s", event->mask, event->name);
return 0;
}
TEST(inotify_issue_38265) {
_cleanup_(rm_rf_physical_and_freep) char *t = NULL;
_cleanup_(sd_event_source_unrefp) sd_event_source *a = NULL, *b = NULL;
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
_cleanup_free_ char *p = NULL;
/* For issue #38265. */
ASSERT_OK(mkdtemp_malloc("/tmp/test-inotify-XXXXXX", &t));
ASSERT_OK(sd_event_default(&e));
/* Create inode data that watches IN_MODIFY */
ASSERT_OK(sd_event_add_inotify(e, &a, t, IN_CREATE | IN_MODIFY, inotify_handler_issue_38265, NULL));
ASSERT_OK(sd_event_add_inotify(e, &b, t, IN_CREATE, inotify_handler_issue_38265, NULL));
/* Then drop the event source that is interested in IN_MODIFY */
ASSERT_NULL(a = sd_event_source_unref(a));
/* Trigger IN_MODIFY (of course with IN_CREATE) */
ASSERT_NOT_NULL(p = path_join(t, "hoge"));
ASSERT_OK(write_string_file(p, "aaa", WRITE_STRING_FILE_CREATE));
for (unsigned i = 1; i < 5; i++) {
log_debug("Running event loop cycle %u to process inotify events...", i);
ASSERT_OK(sd_event_run(e, USEC_PER_MSEC));
}
}
TEST(fork) {
_cleanup_(sd_event_unrefp) sd_event *e = NULL;
int r;