From 9e15e24bdbc695fe4fb65155b4e3bf73db34152b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 25 Oct 2023 03:56:10 +0900 Subject: [PATCH] inotify-util: drop to use pointer outside of the buffer Hopefully fixes many Coverity issues. --- src/basic/inotify-util.c | 37 +++++++++++++++++++++++++++++++++++++ src/basic/inotify-util.h | 26 ++++++++++++-------------- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/basic/inotify-util.c b/src/basic/inotify-util.c index 6da974dec03..ee9b416c873 100644 --- a/src/basic/inotify-util.c +++ b/src/basic/inotify-util.c @@ -4,6 +4,43 @@ #include "inotify-util.h" #include "stat-util.h" +bool inotify_event_next( + union inotify_event_buffer *buffer, + size_t size, + struct inotify_event **iterator, + int log_level) { + + struct inotify_event *e; + size_t offset = 0; + + assert(buffer); + assert(iterator); + + if (*iterator) { + assert((uint8_t*) *iterator >= buffer->raw); + offset = (uint8_t*) *iterator - buffer->raw; + offset += offsetof(struct inotify_event, name) + (*iterator)->len; + } + + if (size == offset) + return false; /* reached end of list */ + + if (size < offset || + size - offset < offsetof(struct inotify_event, name)) { + log_full(log_level, "Received invalid inotify event, ignoring."); + return false; + } + + e = CAST_ALIGN_PTR(struct inotify_event, buffer->raw + offset); + if (size - offset - offsetof(struct inotify_event, name) < e->len) { + log_full(log_level, "Received invalid inotify event, ignoring."); + return false; + } + + *iterator = e; + return true; +} + int inotify_add_watch_fd(int fd, int what, uint32_t mask) { int wd, r; diff --git a/src/basic/inotify-util.h b/src/basic/inotify-util.h index 61951ff3e32..665fdacaa6c 100644 --- a/src/basic/inotify-util.h +++ b/src/basic/inotify-util.h @@ -10,29 +10,27 @@ #define INOTIFY_EVENT_MAX (offsetof(struct inotify_event, name) + NAME_MAX + 1) -#define _FOREACH_INOTIFY_EVENT(e, buffer, sz, log_level, start, end) \ - for (struct inotify_event \ - *start = &((buffer).ev), \ - *end = (struct inotify_event*) ((uint8_t*) start + (sz)), \ - *e = start; \ - (size_t) ((uint8_t*) end - (uint8_t*) e) >= sizeof(struct inotify_event) && \ - ((size_t) ((uint8_t*) end - (uint8_t*) e) >= sizeof(struct inotify_event) + e->len || \ - (log_full(log_level, "Received invalid inotify event, ignoring."), false)); \ - e = (struct inotify_event*) ((uint8_t*) e + sizeof(struct inotify_event) + e->len)) - -#define _FOREACH_INOTIFY_EVENT_FULL(e, buffer, sz, log_level) \ - _FOREACH_INOTIFY_EVENT(e, buffer, sz, log_level, UNIQ_T(start, UNIQ), UNIQ_T(end, UNIQ)) +/* This evaluates arguments multiple times */ +#define FOREACH_INOTIFY_EVENT_FULL(e, buffer, sz, log_level) \ + for (struct inotify_event *e = NULL; \ + inotify_event_next(&buffer, sz, &e, log_level); ) #define FOREACH_INOTIFY_EVENT(e, buffer, sz) \ - _FOREACH_INOTIFY_EVENT_FULL(e, buffer, sz, LOG_DEBUG) + FOREACH_INOTIFY_EVENT_FULL(e, buffer, sz, LOG_DEBUG) #define FOREACH_INOTIFY_EVENT_WARN(e, buffer, sz) \ - _FOREACH_INOTIFY_EVENT_FULL(e, buffer, sz, LOG_WARNING) + FOREACH_INOTIFY_EVENT_FULL(e, buffer, sz, LOG_WARNING) union inotify_event_buffer { struct inotify_event ev; uint8_t raw[INOTIFY_EVENT_MAX]; }; +bool inotify_event_next( + union inotify_event_buffer *buffer, + size_t size, + struct inotify_event **iterator, + int log_level); + int inotify_add_watch_fd(int fd, int what, uint32_t mask); int inotify_add_watch_and_warn(int fd, const char *pathname, uint32_t mask); -- 2.47.3