mirror of
https://github.com/troglobit/finit.git
synced 2026-11-12 16:51:25 +00:00
plugins: tty: possible out-of-bounds read in inotify_event parser
This is a major refactor to use the same construct as in the pidfile.so plugin to parse kernel inotify events for when TTYs are added removed from the system. Found by Coverity Scan. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
32ec25b070
commit
ecaf111a4b
2 files changed
+32
-19
No files matched your search
+32
-18
@@ -53,34 +53,48 @@ static void setup(void)
|
|||||||
_pe("Failed starting TTY watcher");
|
_pe("Failed starting TTY watcher");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void watcher(void *arg, int fd, int events)
|
static void do_tty(char *tty, size_t len, int creat)
|
||||||
{
|
{
|
||||||
char buf[EVENT_SIZE];
|
char name[len + 6];
|
||||||
int len = 0;
|
|
||||||
|
|
||||||
while ((len = read(fd, buf, sizeof(buf)))) {
|
|
||||||
struct inotify_event *notified = (struct inotify_event *)buf;
|
|
||||||
char name[notified->len + 6];
|
|
||||||
struct tty *entry;
|
struct tty *entry;
|
||||||
|
|
||||||
if (-1 == len) {
|
snprintf(name, sizeof(name), "/dev/%s", tty);
|
||||||
if (errno == EINVAL)
|
|
||||||
setup();
|
|
||||||
if (errno == EINTR)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
break; /* Likely EAGAIN */
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "/dev/%s", notified->name);
|
|
||||||
entry = tty_find(name);
|
entry = tty_find(name);
|
||||||
if (entry && tty_enabled(entry)) {
|
if (entry && tty_enabled(entry)) {
|
||||||
if (notified->mask & IN_CREATE)
|
if (creat)
|
||||||
tty_start(entry);
|
tty_start(entry);
|
||||||
else if (entry->pid)
|
else if (entry->pid)
|
||||||
tty_stop(entry);
|
tty_stop(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void watcher(void *arg, int fd, int events)
|
||||||
|
{
|
||||||
|
static char ev_buf[8 *(sizeof(struct inotify_event) + NAME_MAX + 1) + 1];
|
||||||
|
struct inotify_event *ev;
|
||||||
|
ssize_t sz, off;
|
||||||
|
|
||||||
|
sz = read(fd, ev_buf, sizeof(ev_buf) - 1);
|
||||||
|
if (sz <= 0) {
|
||||||
|
_pe("invalid inotify event");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ev_buf[sz] = 0;
|
||||||
|
|
||||||
|
for (off = 0; off < sz; off += sizeof(*ev) + ev->len) {
|
||||||
|
if (off + sizeof(*ev) >= sizeof(ev_buf))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ev = (struct inotify_event *)&ev_buf[off];
|
||||||
|
if (off + sizeof(*ev) + ev->len >= sizeof(ev_buf))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!ev->mask)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
_d("tty %s, event: 0x%08x", ev->name, ev->mask);
|
||||||
|
do_tty(ev->name, ev->len, ev->mask & IN_CREATE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PLUGIN_INIT(plugin_init)
|
PLUGIN_INIT(plugin_init)
|
||||||
|
|||||||
@@ -30,7 +30,6 @@
|
|||||||
#include <lite/queue.h> /* BSD sys/queue.h API */
|
#include <lite/queue.h> /* BSD sys/queue.h API */
|
||||||
|
|
||||||
#define TTY_MAX_ARGS 16
|
#define TTY_MAX_ARGS 16
|
||||||
#define EVENT_SIZE ((sizeof(struct inotify_event) + NAME_MAX + 1))
|
|
||||||
|
|
||||||
struct tty {
|
struct tty {
|
||||||
LIST_ENTRY(tty) link;
|
LIST_ENTRY(tty) link;
|
||||||
|
|||||||
Reference in new issue
Block a user