From 15f4656aeff6ca2f373b5e4e019da59f841caf83 Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Fri, 28 Jan 2022 17:32:18 +0100 Subject: broken, wip --- rvnit.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 85 insertions(+), 17 deletions(-) diff --git a/rvnit.c b/rvnit.c index 345603b..0b65434 100644 --- a/rvnit.c +++ b/rvnit.c @@ -28,7 +28,7 @@ #define MAX_SV 512 // ## not truly portable :/ -#define LOG(fmt, ...) dprintf(selflogfd[1], fmt "\n", ## __VA_ARGS__); +#define LOG(fmt, ...) dprintf(logsocks[1], fmt "\n", ## __VA_ARGS__); enum { UNDEF, @@ -61,6 +61,7 @@ pthread_t logger_thread; int selflogfd[2]; int newlogfd[2]; int globallogfd[2]; +int logsocks[2]; int nullfd; int pid1; @@ -108,13 +109,16 @@ restart(int i) LOG("start %s", services[i].name); if (services[i].logfd[0] == -1) { - pipe(services[i].logfd); - fcntl(services[i].logfd[0], F_SETFL, O_NONBLOCK); - fcntl(services[i].logfd[0], F_SETFD, FD_CLOEXEC); - fcntl(services[i].logfd[1], F_SETFD, FD_CLOEXEC); - write(newlogfd[1], "!", 1); +// pipe(services[i].logfd); +// fcntl(services[i].logfd[0], F_SETFL, O_NONBLOCK); +// fcntl(services[i].logfd[0], F_SETFD, FD_CLOEXEC); +// fcntl(services[i].logfd[1], F_SETFD, FD_CLOEXEC); +// write(newlogfd[1], "!", 1); +// services[i].logfd[0] = globallogfd[0]; +// services[i].logfd[1] = globallogfd[1]; } +#if 0 if (services[i].name[2] == 'L') { for (int j = 0; j < MAX_SV; j++) { if (strcmp(services[i].name + 3, @@ -137,6 +141,7 @@ restart(int i) } } } +#endif if (services[i].name[2] == 'G') { // enable global logger @@ -164,7 +169,7 @@ restart(int i) dup2(2, 1); } else { // pass write end of logger pipe to capture stdout - dup2(services[i].logfd[1], 1); + dup2(logsocks[1], 1); } sleep(delay); setsid(); @@ -351,6 +356,52 @@ socket_loop(void* ignored) return 0; } +ssize_t read_with_pid(int fd, void *buf, size_t count, pid_t *pid) +{ + struct msghdr msgh; + msgh.msg_name = NULL; + msgh.msg_namelen = 0; + + struct iovec iov; + msgh.msg_iov = &iov; + msgh.msg_iovlen = 1; + iov.iov_base = buf; + iov.iov_len = count; + + union { + char buf[CMSG_SPACE(sizeof(struct ucred))]; + /* Space large enough to hold a 'ucred' structure */ + struct cmsghdr align; + } controlMsg; + + msgh.msg_control = controlMsg.buf; + msgh.msg_controllen = sizeof(controlMsg.buf); + + ssize_t nr = recvmsg(fd, &msgh, 0); + if (nr < 0 && errno == ENOTSOCK) { + *pid = 0; + return read(fd, buf, count); + } + + struct cmsghdr *cmsgp = CMSG_FIRSTHDR(&msgh); + + if (cmsgp == NULL || cmsgp->cmsg_len != CMSG_LEN(sizeof(struct ucred))) + return -1; + if (cmsgp->cmsg_level != SOL_SOCKET) + return -1; + if (cmsgp->cmsg_type != SCM_CREDENTIALS) + return -1; + + struct ucred rcred; + memcpy(&rcred, CMSG_DATA(cmsgp), sizeof(struct ucred)); + + printf("Received credentials pid=%ld, uid=%ld, gid=%ld\n", + (long) rcred.pid, (long) rcred.uid, (long) rcred.gid); + + *pid = rcred.pid; + return nr; +} + void * logger_loop(void* ignored) { @@ -368,6 +419,7 @@ logger_loop(void* ignored) fds[nfds].events = POLLIN; nfds++; +#if 0 pthread_mutex_lock(&services_lock); for (int i = 0; i < MAX_SV; i++) { if (!services[i].logged && services[i].logfd[0] > 0) { @@ -377,6 +429,11 @@ logger_loop(void* ignored) } } pthread_mutex_unlock(&services_lock); +#endif + + fds[nfds].fd = globallogfd[1]; + fds[nfds].events = POLLIN; + nfds++; int n = poll(fds, nfds, -1); if (n < 0) { @@ -400,7 +457,7 @@ logger_loop(void* ignored) for (nfds_t j = 0; j < nfds; j++) { if (fds[j].revents & POLLNVAL) { - dprintf(2, "invalid fd %d\n", fds[j].revents); + dprintf(2, "invalid fd %d\n", fds[j].fd); continue; } @@ -430,12 +487,15 @@ logger_loop(void* ignored) "%Y-%m-%dT%H:%M:%S", gmtime(&now.tv_sec)); char buf[4096]; - ssize_t rd = read(fds[j].fd, buf, sizeof buf); + pid_t pid = -1; + ssize_t rd = read_with_pid(fds[j].fd, + buf, sizeof buf, &pid); if (rd < 0) { - perror("rvnit: read"); + perror("rvnit: read_with_pid"); continue; } +#if 0 if (rd < (int)sizeof buf && buf[rd - 1] != '\n') { // sometimes processes use multiple write calls // for one line, give them 25msec to do try to @@ -445,9 +505,9 @@ logger_loop(void* ignored) if (rd2 > 0) rd += rd2; } +#endif const char *sv = ""; - long pid = -1; int pass_thru = 0; if (fds[j].fd == selflogfd[0]) { @@ -457,9 +517,8 @@ logger_loop(void* ignored) } else { pthread_mutex_lock(&services_lock); for (int i = 0; i < MAX_SV; i++) { - if (services[i].logfd[0] == fds[j].fd) { + if (services[i].display_pid == pid) { sv = services[i].name; - pid = services[i].display_pid; break; } } @@ -476,7 +535,7 @@ logger_loop(void* ignored) int r = dprintf(globallogfd[1], "%s.%05ld %s[%ld]: %.*s\n", timestamp, now.tv_nsec / 10000, - sv, pid, (int)(eol - s), s); + sv, (long)pid, (int)(eol - s), s); if (!use_global_log || pass_thru || r < 0) { /* print own messages, and messages during boot/shutdown, or when writing @@ -485,7 +544,7 @@ logger_loop(void* ignored) stall here) */ dprintf(2, "%s.%05ld %s[%ld]: %.*s\n", timestamp, now.tv_nsec / 10000, - sv, pid, (int)(eol - s), s); + sv, (long)pid, (int)(eol - s), s); } s = eol + 1; @@ -713,12 +772,21 @@ main(int argc, char *argv[]) fcntl(newlogfd[0], F_SETFD, FD_CLOEXEC); fcntl(newlogfd[1], F_SETFD, FD_CLOEXEC); - pipe(globallogfd); + pipe(globallogfd); // don't care about read end fcntl(globallogfd[1], F_SETFL, O_NONBLOCK); fcntl(globallogfd[0], F_SETFD, FD_CLOEXEC); fcntl(globallogfd[1], F_SETFD, FD_CLOEXEC); + socketpair(AF_UNIX, SOCK_STREAM, 0, logsocks); + int optval = 1; + setsockopt(logsocks[0], SOL_SOCKET, SO_PASSCRED, &optval, sizeof optval); + setsockopt(logsocks[1], SOL_SOCKET, SO_PASSCRED, &optval, sizeof optval); + // don't care about write end + fcntl(logsocks[0], F_SETFL, O_NONBLOCK); + fcntl(logsocks[0], F_SETFD, FD_CLOEXEC); + fcntl(logsocks[1], F_SETFD, FD_CLOEXEC); + LOG("booting"); pid1 = real_pid1 = (getpid() == 1); @@ -1096,7 +1164,7 @@ cont4: else dprintf(selflogfd[1], "shutdown\n"); - close(globallogfd[1]); +// close(globallogfd[1]); close(selflogfd[1]); pthread_join(logger_thread, 0); -- cgit 1.4.1