diff options
Diffstat (limited to 'passt-repair.c')
-rw-r--r-- | passt-repair.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/passt-repair.c b/passt-repair.c index 120f7aa..86f0293 100644 --- a/passt-repair.c +++ b/passt-repair.c @@ -111,14 +111,14 @@ int main(int argc, char **argv) } if ((sb.st_mode & S_IFMT) == S_IFDIR) { - char buf[sizeof(struct inotify_event) + NAME_MAX + 1]; + char buf[sizeof(struct inotify_event) + NAME_MAX + 1] + __attribute__ ((aligned(__alignof__(struct inotify_event)))); const struct inotify_event *ev; char path[PATH_MAX + 1]; + bool found = false; ssize_t n; int fd; - ev = (struct inotify_event *)buf; - if ((fd = inotify_init1(IN_CLOEXEC)) < 0) { fprintf(stderr, "inotify_init1: %i\n", errno); _exit(1); @@ -130,6 +130,8 @@ int main(int argc, char **argv) } do { + char *p; + n = read(fd, buf, sizeof(buf)); if (n < 0) { fprintf(stderr, "inotify read: %i", errno); @@ -138,11 +140,27 @@ int main(int argc, char **argv) if (n < (ssize_t)sizeof(*ev)) { fprintf(stderr, "Short inotify read: %zi", n); - _exit(1); + continue; + } + + for (p = buf; p < buf + n; p += sizeof(*ev) + ev->len) { + ev = (const struct inotify_event *)p; + + if (ev->len >= REPAIR_EXT_LEN && + !memcmp(ev->name + + strnlen(ev->name, ev->len) - + REPAIR_EXT_LEN, + REPAIR_EXT, REPAIR_EXT_LEN)) { + found = true; + break; + } } - } while (ev->len < REPAIR_EXT_LEN || - memcmp(ev->name + strlen(ev->name) - REPAIR_EXT_LEN, - REPAIR_EXT, REPAIR_EXT_LEN)); + } while (!found); + + if (ev->len > NAME_MAX + 1 || ev->name[ev->len] != '\0') { + fprintf(stderr, "Invalid filename from inotify\n"); + _exit(1); + } snprintf(path, sizeof(path), "%s/%s", argv[1], ev->name); if ((stat(path, &sb))) { |