From 612edc04f50526ba4e21e4e65142a34f964f95ef Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Fri, 11 Sep 2026 13:13:33 +0000 Subject: s6-sudod: fix client error reporting missing in several places --- src/conn-tools/s6-sudod.c | 96 +++++++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 33 deletions(-) (limited to 'src') diff --git a/src/conn-tools/s6-sudod.c b/src/conn-tools/s6-sudod.c index c455c32..bc82917 100644 --- a/src/conn-tools/s6-sudod.c +++ b/src/conn-tools/s6-sudod.c @@ -58,16 +58,33 @@ static int handle_signals (pid_t pid, int *wstat) } } +static void fail (int e) +{ + tain deadline ; + char c = e ; + buffer_putnoflush(buffer_1small, &c, 1) ; + tain_addsec_g(&deadline, 1) ; + if (!buffer_timed_flush_g(buffer_1small, &deadline)) + strerr_diefusys(111, "send error code to client") ; +} + +static void faile (void) +{ + int e = errno ; + fail(e) ; + errno = e ; +} + int main (int argc, char const *const *argv, char const *const *envp) { iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .fd = 0, .events = 0, .revents = 0 } } ; unixmessage m ; + tain deadline = TAIN_INFINITE_RELATIVE ; unsigned int nullfds = 0 ; pid_t pid ; int wstat ; size_t envc = env_len(envp) ; uint32_t cargc, cenvc, carglen, cenvlen ; - tain deadline = TAIN_INFINITE_RELATIVE ; PROG = "s6-sudod" ; { @@ -91,42 +108,51 @@ int main (int argc, char const *const *argv, char const *const *envp) if (t) tain_from_millisecs(&deadline, t) ; } - if ((ndelay_on(0) < 0) || (ndelay_on(1) < 0)) - strerr_diefu1sys(111, "make socket non-blocking") ; + if ((ndelay_on(0) == -1) || (ndelay_on(1) == -1)) + strerr_diefusys(111, "make socket non-blocking") ; tain_now_set_stopwatch_g() ; tain_add_g(&deadline, &deadline) ; buffer_putnoflush(buffer_1small, S6_SUDO_BANNERB, S6_SUDO_BANNERB_LEN) ; if (!buffer_timed_flush_g(buffer_1small, &deadline)) - strerr_diefu1sys(111, "write banner to client") ; + strerr_diefusys(111, "write banner to client") ; + if (unixmessage_timed_receive_g(unixmessage_receiver_0, &m, &deadline) <= 0) - strerr_diefu1sys(111, "read message from client") ; + strerr_diefusys(111, "read message from client") ; if (m.nfds != 3) - strerr_dief1x(100, "client did not send 3 fds") ; + strerr_dief(100, "client did not send 3 fds") ; if (m.len < 16 + S6_SUDO_BANNERA_LEN) - strerr_dief1x(100, "wrong client message") ; + strerr_dief(100, "wrong client message") ; if (strncmp(m.s, S6_SUDO_BANNERA, S6_SUDO_BANNERA_LEN)) - strerr_dief1x(100, "wrong client banner") ; + strerr_dief(100, "wrong client banner") ; uint32_unpack_big(m.s + S6_SUDO_BANNERA_LEN, &cargc) ; uint32_unpack_big(m.s + S6_SUDO_BANNERA_LEN + 4, &cenvc) ; uint32_unpack_big(m.s + S6_SUDO_BANNERA_LEN + 8, &carglen) ; uint32_unpack_big(m.s + S6_SUDO_BANNERA_LEN + 12, &cenvlen) ; if (S6_SUDO_BANNERA_LEN + 16 + carglen + cenvlen != m.len) - strerr_dief1x(100, "wrong client argc/envlen") ; + strerr_dief(100, "wrong client argc/envlen") ; if ((cargc > 131072) || (cenvc > 131072)) - strerr_dief1x(100, "too many args/envvars from client") ; - if (argc + cargc == 0) strerr_dief1x(100, "client and server args both empty") ; + strerr_dief(100, "too many args/envvars from client") ; + if (argc + cargc == 0) strerr_dief(100, "client and server args both empty") ; if (nullfds & 1) { close(m.fds[0]) ; m.fds[0] = open2("/dev/null", O_RDONLY) ; - if (m.fds[0] < 0) strerr_diefu2sys(111, "open /dev/null for ", "reading") ; + if (m.fds[0] < 0) + { + faile() ; + strerr_diefusys(111, "open /dev/null for ", "reading") ; + } } if (nullfds & 2) { close(m.fds[1]) ; m.fds[1] = open2("/dev/null", O_WRONLY) ; - if (m.fds[1] < 0) strerr_diefu2sys(111, "open /dev/null for ", "writing") ; + if (m.fds[1] < 0) + { + faile() ; + strerr_diefusys(111, "open /dev/null for ", "writing") ; + } } if (nullfds & 4) { @@ -148,18 +174,12 @@ int main (int argc, char const *const *argv, char const *const *envp) for (i = 0 ; i <= envc ; i++) tenvp[i] = envp[i] ; if (!env_make(targv + argc, cargc, m.s + S6_SUDO_BANNERA_LEN + 16, carglen)) { - char c = errno ; - buffer_putnoflush(buffer_1small, &c, 1) ; - buffer_timed_flush_g(buffer_1small, &deadline) ; - errno = c ; + faile() ; strerr_diefu1sys(111, "make child argv") ; } if (!env_make(tenvp + envc + 1, cenvc, m.s + S6_SUDO_BANNERA_LEN + 16 + carglen, cenvlen)) { - char c = errno ; - buffer_putnoflush(buffer_1small, &c, 1) ; - buffer_timed_flush_g(buffer_1small, &deadline) ; - errno = c ; + faile() ; strerr_diefu1sys(111, "make child envp") ; } targv[argc + cargc] = 0 ; @@ -171,21 +191,31 @@ int main (int argc, char const *const *argv, char const *const *envp) size_t len = str_chr(var, '=') ; if (!var[len]) { - char c = EINVAL ; - buffer_putnoflush(buffer_1small, &c, 1) ; - buffer_timed_flush_g(buffer_1small, &deadline) ; - strerr_dief1x(100, "bad environment from client") ; + fail(EINVAL) ; + strerr_dief(100, "bad environment from client") ; } for (; j < envc ; j++) if (!strncmp(var, tenvp[j], len+1)) break ; if ((j < envc) && !tenvp[j][len+1]) tenvp[j] = var ; } x[0].fd = selfpipe_init() ; - if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ; - if (!selfpipe_trap(SIGCHLD)) strerr_diefu1sys(111, "trap SIGCHLD") ; + if (x[0].fd == -1) + { + faile() ; + strerr_diefusys(111, "selfpipe_init") ; + } + if (!selfpipe_trap(SIGCHLD)) + { + faile() ; + strerr_diefusys(111, "trap SIGCHLD") ; + } pid = cspawn(targv[0], targv, tenvp, CSPAWN_FLAGS_SELFPIPE_FINISH, fa, 3) ; - if (!pid) strerr_diefu2sys(111, "spawn ", targv[0]) ; + if (!pid) + { + faile() ; + strerr_diefusys(111, "spawn ", targv[0]) ; + } } fd_close(m.fds[0]) ; @@ -194,11 +224,11 @@ int main (int argc, char const *const *argv, char const *const *envp) unixmessage_receiver_free(unixmessage_receiver_0) ; buffer_putnoflush(buffer_1small, "", 1) ; if (!buffer_timed_flush_g(buffer_1small, &deadline)) - strerr_diefu1sys(111, "send confirmation to client") ; + strerr_diefusys(111, "send confirmation to client") ; for (;;) { - if (iopause_g(x, 1 + !x[1].revents, 0) < 0) strerr_diefu1sys(111, "iopause") ; + if (iopause_g(x, 1 + !x[1].revents, 0) == -1) strerr_diefusys(111, "iopause") ; if (x[0].revents && handle_signals(pid, &wstat)) break ; if (x[1].revents && !(nullfds & 8)) { @@ -213,10 +243,10 @@ int main (int argc, char const *const *argv, char const *const *envp) char pack[UINT_PACK] ; uint_pack_big(pack, (unsigned int)wstat) ; buffer_putnoflush(buffer_1small, pack, UINT_PACK) ; - if (ndelay_off(1) < 0) - strerr_diefu1sys(111, "set stdout blocking") ; + if (ndelay_off(1) == -1) + strerr_diefusys(111, "set stdout blocking") ; if (!buffer_flush(buffer_1small)) - strerr_diefu1sys(111, "write status to client") ; + strerr_diefusys(111, "write status to client") ; } return 0 ; } -- cgit v1.3.1