Use re-entrant locks on stdio

This commit is contained in:
Justine Tunney 2022-05-22 08:13:13 -07:00
parent 4e9662cbc7
commit 1f229e4efc
78 changed files with 427 additions and 179 deletions

View file

@ -29,6 +29,7 @@
#include "third_party/mbedtls/ctr_drbg.h"
#include "third_party/mbedtls/ecp.h"
#include "third_party/mbedtls/error.h"
#include "third_party/mbedtls/net_sockets.h"
#include "third_party/mbedtls/platform.h"
#include "third_party/mbedtls/ssl.h"
#include "tool/build/lib/eztls.h"

View file

@ -51,6 +51,7 @@
#include "libc/time/time.h"
#include "libc/x/x.h"
#include "net/https/https.h"
#include "third_party/mbedtls/net_sockets.h"
#include "third_party/mbedtls/ssl.h"
#include "third_party/zlib/zlib.h"
#include "tool/build/lib/eztls.h"
@ -112,6 +113,7 @@ static const struct addrinfo kResolvHints = {.ai_family = AF_INET,
int g_sock;
char *g_prog;
long g_backoff;
char *g_runitd;
jmp_buf g_jmpbuf;
uint16_t g_sshport;
@ -308,7 +310,7 @@ TryAgain:
freeaddrinfo(ai);
}
static void Send(const void *output, size_t outputsize) {
static bool Send(const void *output, size_t outputsize) {
int rc, have;
static bool once;
static z_stream zs;
@ -326,11 +328,17 @@ static void Send(const void *output, size_t outputsize) {
rc = deflate(&zs, Z_SYNC_FLUSH);
CHECK_NE(Z_STREAM_ERROR, rc);
have = sizeof(zbuf) - zs.avail_out;
CHECK_EQ(have, mbedtls_ssl_write(&ezssl, zbuf, have));
rc = mbedtls_ssl_write(&ezssl, zbuf, have);
if (rc == MBEDTLS_ERR_NET_CONN_RESET) {
usleep((g_backoff = (g_backoff + 1000) * 2));
return false;
}
CHECK_EQ(have, rc);
} while (!zs.avail_out);
return true;
}
void SendRequest(void) {
int SendRequest(void) {
int fd;
char *p;
size_t i;
@ -357,22 +365,30 @@ void SendRequest(void) {
q = mempcpy(q, name, namesize);
assert(hdrsize == q - hdr);
DEBUGF("running %s on %s", g_prog, g_hostname);
Send(hdr, hdrsize);
Send(p, progsize);
CHECK_EQ(0, EzTlsFlush(&ezbio, 0, 0));
if (Send(hdr, hdrsize) && Send(p, progsize)) {
if (!(rc = EzTlsFlush(&ezbio, 0, 0))) {
rc = 0;
} else if (rc == MBEDTLS_ERR_NET_CONN_RESET) {
rc = -1;
} else {
CHECK_EQ(0, rc);
}
} else {
rc = -1;
}
CHECK_NE(-1, munmap(p, st.st_size));
CHECK_NE(-1, close(fd));
return rc;
}
bool Recv(unsigned char *p, size_t n) {
size_t i, rc;
static long backoff;
for (i = 0; i < n; i += rc) {
do {
rc = mbedtls_ssl_read(&ezssl, p + i, n - i);
} while (rc == MBEDTLS_ERR_SSL_WANT_READ);
if (!rc || rc == MBEDTLS_ERR_NET_CONN_RESET) {
usleep((backoff = (backoff + 1000) * 2));
usleep((g_backoff = (g_backoff + 1000) * 2));
return false;
} else if (rc < 0) {
TlsDie("read response failed", rc);
@ -442,8 +458,7 @@ int RunOnHost(char *spec) {
WARNF("warning: got connection reset in handshake");
close(g_sock);
}
SendRequest();
} while ((rc = ReadResponse()) == -1);
} while ((rc = SendRequest()) == -1 || (rc = ReadResponse()) == -1);
return rc;
}

View file

@ -42,6 +42,7 @@
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/poll.h"
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/consts/so.h"
#include "libc/sysv/consts/sock.h"
#include "libc/sysv/consts/sol.h"
@ -110,7 +111,12 @@ void OnInterrupt(int sig) {
void OnChildTerminated(int sig) {
int ws, pid;
sigset_t ss, oldss;
sigfillset(&ss);
sigdelset(&ss, SIGTERM);
sigprocmask(SIG_BLOCK, &ss, &oldss);
for (;;) {
INFOF("waitpid");
if ((pid = waitpid(-1, &ws, WNOHANG)) != -1) {
if (pid) {
if (WIFEXITED(ws)) {
@ -127,6 +133,7 @@ void OnChildTerminated(int sig) {
FATALF("waitpid failed in sigchld");
}
}
sigprocmask(SIG_SETMASK, &oldss, 0);
}
wontreturn void ShowUsage(FILE *f, int rc) {
@ -229,6 +236,7 @@ void SendExitMessage(int rc) {
msg[0 + 3] = (RUNITD_MAGIC & 0x000000ff) >> 000;
msg[4] = kRunitExit;
msg[5] = rc;
INFOF("mbedtls_ssl_write");
CHECK_EQ(sizeof(msg), mbedtls_ssl_write(&ezssl, msg, sizeof(msg)));
CHECK_EQ(0, EzTlsFlush(&ezbio, 0, 0));
}
@ -247,6 +255,7 @@ void SendOutputFragmentMessage(enum RunitCommand kind, unsigned char *buf,
msg[5 + 1] = (size & 0x00ff0000) >> 020;
msg[5 + 2] = (size & 0x0000ff00) >> 010;
msg[5 + 3] = (size & 0x000000ff) >> 000;
INFOF("mbedtls_ssl_write");
CHECK_EQ(sizeof(msg), mbedtls_ssl_write(&ezssl, msg, sizeof(msg)));
while (size) {
CHECK_NE(-1, (rc = mbedtls_ssl_write(&ezssl, buf, size)));
@ -294,6 +303,7 @@ void Recv(void *output, size_t outputsize) {
// get another fixed-size data packet from network
// pass along error conditions to caller
// pass along eof condition to zlib
INFOF("mbedtls_ssl_read");
received = mbedtls_ssl_read(&ezssl, buf, sizeof(buf));
if (received < 0) TlsDie("read failed", received);
// decompress packet completely
@ -347,12 +357,14 @@ void HandleClient(void) {
/* read request to run program */
addrsize = sizeof(addr);
INFOF("accept");
CHECK_NE(-1, (g_clifd = accept4(g_servfd, &addr, &addrsize, SOCK_CLOEXEC)));
if (fork()) {
close(g_clifd);
return;
}
EzFd(g_clifd);
INFOF("EzHandshake");
EzHandshake();
addrstr = gc(DescribeAddress(&addr));
DEBUGF("%s %s %s", gc(DescribeAddress(&g_servaddr)), "accepted", addrstr);
@ -376,6 +388,7 @@ void HandleClient(void) {
}
CHECK_NE(-1, (g_exefd = creat(g_exepath, 0700)));
LOGIFNEG1(ftruncate(g_exefd, filesize));
INFOF("xwrite");
CHECK_NE(-1, xwrite(g_exefd, exe, filesize));
LOGIFNEG1(close(g_exefd));
@ -425,6 +438,7 @@ void HandleClient(void) {
fds[0].events = POLLIN;
fds[1].fd = pipefds[0];
fds[1].events = POLLIN;
INFOF("poll");
events = poll(fds, ARRAYLEN(fds), (deadline - now) * 1000);
CHECK_NE(-1, events); // EINTR shouldn't be possible
if (fds[0].revents) {
@ -440,6 +454,7 @@ void HandleClient(void) {
LOGIFNEG1(unlink(g_exepath));
_exit(1);
}
INFOF("read");
got = read(pipefds[0], g_buf, sizeof(g_buf));
CHECK_NE(-1, got); // EINTR shouldn't be possible
if (!got) {
@ -449,6 +464,7 @@ void HandleClient(void) {
fwrite(g_buf, got, 1, stderr);
SendOutputFragmentMessage(kRunitStderr, g_buf, got);
}
INFOF("waitpid");
CHECK_NE(-1, waitpid(child, &wstatus, 0)); // EINTR shouldn't be possible
if (WIFEXITED(wstatus)) {
if (WEXITSTATUS(wstatus)) {
@ -463,6 +479,7 @@ void HandleClient(void) {
}
LOGIFNEG1(unlink(g_exepath));
SendExitMessage(exitcode);
INFOF("mbedtls_ssl_close_notify");
mbedtls_ssl_close_notify(&ezssl);
LOGIFNEG1(close(g_clifd));
_exit(0);
@ -524,7 +541,7 @@ void Daemonize(void) {
int main(int argc, char *argv[]) {
int i;
SetupPresharedKeySsl(MBEDTLS_SSL_IS_SERVER, GetRunitPsk());
/* __log_level = kLogDebug; */
__log_level = kLogInfo;
GetOpts(argc, argv);
for (i = 3; i < 16; ++i) close(i);
errno = 0;

View file

@ -108,6 +108,7 @@
"protip"
"nxbitsafe"
"vforksafe"
"threadsafe"
"preinitsafe"
"asyncsignalsafe"
"notasyncsignalsafe"

View file

@ -146,6 +146,7 @@
#include "third_party/mbedtls/iana.h"
#include "third_party/mbedtls/md.h"
#include "third_party/mbedtls/md5.h"
#include "third_party/mbedtls/net_sockets.h"
#include "third_party/mbedtls/oid.h"
#include "third_party/mbedtls/pk.h"
#include "third_party/mbedtls/rsa.h"

View file

@ -52,6 +52,7 @@
#include "third_party/mbedtls/ctr_drbg.h"
#include "third_party/mbedtls/debug.h"
#include "third_party/mbedtls/error.h"
#include "third_party/mbedtls/net_sockets.h"
#include "third_party/mbedtls/ssl.h"
#define OPTS "BIqksvzX:H:C:m:"