]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
inotify-util: drop to use pointer outside of the buffer
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 24 Oct 2023 18:56:10 +0000 (03:56 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 26 Oct 2023 07:08:28 +0000 (09:08 +0200)
Hopefully fixes many Coverity issues.

src/basic/inotify-util.c
src/basic/inotify-util.h

index 6da974dec03315089787f1f3ffb11c01f95b4270..ee9b416c8735d555c447a7dbaab083fed79df3f4 100644 (file)
@@ -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;
 
index 61951ff3e3244f0a1b460497e6e0c063034c1dae..665fdacaa6cfe4eae65ea2be338d0d71f123a33a 100644 (file)
 
 #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);