diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2024-05-03 20:43:37 +0000 |
---|---|---|
committer | Laurent Bercot <ska@appnovation.com> | 2024-05-03 20:43:37 +0000 |
commit | 6d0c114f57bcd554383a41c9ca791e25e95b81b5 (patch) | |
tree | 7ed5e04fa40a18c9e7d1858ae073b9ef602faa3b /src/libs6 | |
parent | 35709f34aaafad99c89d9848b68e3d211b7e0f02 (diff) | |
download | s6-6d0c114f57bcd554383a41c9ca791e25e95b81b5.tar.xz |
Restore cleanups in s6-ftrigrd; fix an old bug and a new bug
ftrigw_clean() didn't clean properly.
ftrig1_make() didn't give enough perms to the fifo, notification
could fail in certain cases.
Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src/libs6')
-rw-r--r-- | src/libs6/ftrig1_make.c | 2 | ||||
-rw-r--r-- | src/libs6/ftrigw_clean.c | 8 | ||||
-rw-r--r-- | src/libs6/s6-ftrigrd.c | 49 |
3 files changed, 46 insertions, 13 deletions
diff --git a/src/libs6/ftrig1_make.c b/src/libs6/ftrig1_make.c index 04c8c73..5c38e4b 100644 --- a/src/libs6/ftrig1_make.c +++ b/src/libs6/ftrig1_make.c @@ -23,7 +23,7 @@ int ftrig1_make (ftrig1_t *f, char const *path) tmp[pathlen + 2 + FTRIG1_PREFIXLEN] = ':' ; if (!timestamp(tmp + pathlen + 3 + FTRIG1_PREFIXLEN)) return 0 ; memcpy(tmp + pathlen + FTRIG1_PREFIXLEN + 28, ":XXXXXX", 8) ; - ff.fd = mkptemp2(tmp, O_NONBLOCK|O_CLOEXEC) ; + ff.fd = mkptemp3(tmp, 0622, O_NONBLOCK|O_CLOEXEC) ; if (ff.fd == -1) return 0 ; ff.fdw = open_write(tmp) ; if (ff.fdw == -1) goto err1 ; diff --git a/src/libs6/ftrigw_clean.c b/src/libs6/ftrigw_clean.c index 3ad9e3a..e540aba 100644 --- a/src/libs6/ftrigw_clean.c +++ b/src/libs6/ftrigw_clean.c @@ -15,9 +15,9 @@ int ftrigw_clean (char const *path) DIR *dir = opendir(path) ; if (!dir) return 0 ; { - char tmp[pathlen + FTRIG1_PREFIXLEN + 45] ; + char tmp[pathlen + FTRIG1_PREFIXLEN + 35] ; memcpy(tmp, path, pathlen) ; - tmp[pathlen] = '/' ; tmp[pathlen + FTRIG1_PREFIXLEN + 44] = 0 ; + tmp[pathlen] = '/' ; tmp[pathlen + FTRIG1_PREFIXLEN + 34] = 0 ; for (;;) { direntry *d ; @@ -26,8 +26,8 @@ int ftrigw_clean (char const *path) d = readdir(dir) ; if (!d) break ; if (strncmp(d->d_name, FTRIG1_PREFIX, FTRIG1_PREFIXLEN)) continue ; - if (strlen(d->d_name) != FTRIG1_PREFIXLEN + 43) continue ; - memcpy(tmp + pathlen + 1, d->d_name, FTRIG1_PREFIXLEN + 43) ; + if (strlen(d->d_name) != FTRIG1_PREFIXLEN + 33) continue ; + memcpy(tmp + pathlen + 1, d->d_name, FTRIG1_PREFIXLEN + 33) ; fd = open_write(tmp) ; if (fd >= 0) fd_close(fd) ; else if ((errno == ENXIO) && (unlink(tmp) < 0)) e = errno ; diff --git a/src/libs6/s6-ftrigrd.c b/src/libs6/s6-ftrigrd.c index 202ea31..b6ca40b 100644 --- a/src/libs6/s6-ftrigrd.c +++ b/src/libs6/s6-ftrigrd.c @@ -48,26 +48,40 @@ struct ftrigio_s static genalloc g = GENALLOC_ZERO ; /* ftrigio */ +static void ftrigio_deepfree (ftrigio *p) +{ + ftrig1_free(&p->trig) ; + stralloc_free(&p->sa) ; + regfree(&p->re) ; +} + +static void cleanup (void) +{ + size_t n = genalloc_len(ftrigio, &g) ; + ftrigio *a = genalloc_s(ftrigio, &g) ; + for (size_t i = 0 ; i < n ; i++) ftrigio_deepfree(a + i) ; + genalloc_setlen(ftrigio, &g, 0) ; +} + static void trig (uint16_t id, char what, char info) { char pack[4] ; uint16_pack_big(pack, id) ; pack[2] = what ; pack[3] = info ; if (!textmessage_put(textmessage_sender_x, pack, 4)) + { + cleanup() ; strerr_diefu1sys(111, "build answer") ; + } } static void answer (unsigned char c) { if (!textmessage_put(textmessage_sender_1, (char *)&c, 1)) + { + cleanup() ; strerr_diefu1sys(111, "textmessage_put") ; -} - -static void ftrigio_deepfree (ftrigio *p) -{ - ftrig1_free(&p->trig) ; - stralloc_free(&p->sa) ; - regfree(&p->re) ; + } } static void remove (size_t i) @@ -91,7 +105,11 @@ static inline int ftrigio_read (ftrigio *p) if (!r) break ; if (r < 0) return (trig(p->id, 'd', errno), 0) ; blen = buffer_len(&p->b) ; - if (!stralloc_readyplus(&p->sa, blen+1)) dienomem() ; + if (!stralloc_readyplus(&p->sa, blen+1)) + { + cleanup() ; + dienomem() ; + } buffer_getnofill(&p->b, p->sa.s + p->sa.len, blen) ; p->sa.len += blen ; p->sa.s[p->sa.len] = 0 ; @@ -111,7 +129,10 @@ static int parse_protocol (struct iovec const *v, void *context) char const *s = v->iov_base ; uint16_t id ; if (v->iov_len < 3) + { + cleanup() ; strerr_dief1x(100, "invalid client request") ; + } uint16_unpack_big(s, &id) ; switch (s[2]) { @@ -174,6 +195,7 @@ static int parse_protocol (struct iovec const *v, void *context) break ; } default : + cleanup() ; strerr_dief1x(100, "invalid client request") ; } (void)context ; @@ -216,7 +238,10 @@ int main (void) } if (iopause(x, 3 + n, 0, 0) < 0) + { + cleanup() ; strerr_diefu1sys(111, "iopause") ; + } /* client closed */ if ((x[0].revents | x[1].revents) & IOPAUSE_EXCEPT) break ; @@ -224,10 +249,16 @@ int main (void) /* client is reading */ if (x[1].revents & IOPAUSE_WRITE) if (!textmessage_sender_flush(textmessage_sender_1) && !error_isagain(errno)) + { + cleanup() ; strerr_diefu1sys(111, "flush stdout") ; + } if (x[2].revents & IOPAUSE_WRITE) if (!textmessage_sender_flush(textmessage_sender_x) && !error_isagain(errno)) + { + cleanup() ; return 1 ; + } /* scan listening ftrigs */ for (i = 0 ; i < genalloc_len(ftrigio, &g) ; i++) @@ -243,9 +274,11 @@ int main (void) if (textmessage_handle(textmessage_receiver_0, &parse_protocol, 0) < 0) { if (errno == EPIPE) break ; /* normal exit */ + cleanup() ; strerr_diefu1sys(111, "handle messages from client") ; } } } + cleanup() ; return 0 ; } |