rpki-client starts a few processes and it can do this a bit more elegant by factoring the common code out into process_start(). This makes the code in main a fair bit shorter.
I decided to move all pledge calles into the individual processes. In my opinion there is little benefit in keeping them in main. -- :wq Claudio Index: http.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/http.c,v retrieving revision 1.54 diff -u -p -r1.54 http.c --- http.c 11 Mar 2022 09:57:54 -0000 1.54 +++ http.c 11 Apr 2022 14:04:57 -0000 @@ -1773,6 +1773,9 @@ proc_http(char *bind_addr, int fd) struct http_request *req, *nr; struct ibuf *b, *inbuf = NULL; + if (pledge("stdio rpath inet dns recvfd", NULL) == -1) + err(1, "pledge"); + if (bind_addr != NULL) { struct addrinfo hints, *res; Index: main.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v retrieving revision 1.192 diff -u -p -r1.192 main.c --- main.c 4 Apr 2022 16:02:54 -0000 1.192 +++ main.c 11 Apr 2022 14:28:51 -0000 @@ -703,6 +703,34 @@ check_fs_size(int fd, const char *cached } } +static pid_t +process_start(const char *title, int *fd) +{ + int fl = SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK; + pid_t pid; + int pair[2]; + + if (socketpair(AF_UNIX, fl, 0, pair) == -1) + err(1, "socketpair"); + if ((pid = fork()) == -1) + err(1, "fork"); + + if (pid == 0) { + setproctitle("%s", title); + /* change working directory to the cache directory */ + if (fchdir(cachefd) == -1) + err(1, "fchdir"); + if (timeout) + alarm(timeout); + close(pair[1]); + *fd = pair[0]; + } else { + close(pair[0]); + *fd = pair[1]; + } + return pid; +} + void suicide(int sig __attribute__((unused))) { @@ -714,11 +742,9 @@ suicide(int sig __attribute__((unused))) int main(int argc, char *argv[]) { - int rc, c, st, proc, rsync, http, rrdp, hangup = 0; - int fl = SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK; + int fd, rc, c, st, proc, rsync, http, rrdp, hangup = 0; size_t i; pid_t pid, procpid, rsyncpid, httppid, rrdppid; - int fd[2]; struct pollfd pfd[NPFD]; struct msgbuf *queues[NPFD]; struct ibuf *b, *httpbuf = NULL, *procbuf = NULL; @@ -869,33 +895,12 @@ main(int argc, char *argv[]) * manifests, certificates, etc.) and returning contents. */ - if (socketpair(AF_UNIX, fl, 0, fd) == -1) - err(1, "socketpair"); - if ((procpid = fork()) == -1) - err(1, "fork"); - + procpid = process_start("parser", &fd); if (procpid == 0) { - close(fd[1]); - - setproctitle("parser"); - /* change working directory to the cache directory */ - if (fchdir(cachefd) == -1) - err(1, "fchdir"); - - if (timeout) - alarm(timeout); - - /* Only allow access to the cache directory. */ - if (unveil(".", "r") == -1) - err(1, "%s: unveil", cachedir); - if (pledge("stdio rpath", NULL) == -1) - err(1, "pledge"); - proc_parser(fd[0]); + proc_parser(fd); errx(1, "parser process returned"); } - - close(fd[0]); - proc = fd[1]; + proc = fd; /* * Create a process that will do the rsync'ing. @@ -905,32 +910,13 @@ main(int argc, char *argv[]) */ if (!noop) { - if (socketpair(AF_UNIX, fl, 0, fd) == -1) - err(1, "socketpair"); - if ((rsyncpid = fork()) == -1) - err(1, "fork"); - + rsyncpid = process_start("rsync", &fd); if (rsyncpid == 0) { close(proc); - close(fd[1]); - - setproctitle("rsync"); - /* change working directory to the cache directory */ - if (fchdir(cachefd) == -1) - err(1, "fchdir"); - - if (timeout) - alarm(timeout); - - if (pledge("stdio rpath proc exec unveil", NULL) == -1) - err(1, "pledge"); - - proc_rsync(rsync_prog, bind_addr, fd[0]); + proc_rsync(rsync_prog, bind_addr, fd); errx(1, "rsync process returned"); } - - close(fd[0]); - rsync = fd[1]; + rsync = fd; } else { rsync = -1; rsyncpid = -1; @@ -942,34 +928,16 @@ main(int argc, char *argv[]) * where the data should be written to. */ - if (!noop) { - if (socketpair(AF_UNIX, fl, 0, fd) == -1) - err(1, "socketpair"); - if ((httppid = fork()) == -1) - err(1, "fork"); + if (!noop && rrdpon) { + httppid = process_start("http", &fd); if (httppid == 0) { close(proc); close(rsync); - close(fd[1]); - - setproctitle("http"); - /* change working directory to the cache directory */ - if (fchdir(cachefd) == -1) - err(1, "fchdir"); - - if (timeout) - alarm(timeout); - - if (pledge("stdio rpath inet dns recvfd", NULL) == -1) - err(1, "pledge"); - - proc_http(bind_addr, fd[0]); + proc_http(bind_addr, fd); errx(1, "http process returned"); } - - close(fd[0]); - http = fd[1]; + http = fd; } else { http = -1; httppid = -1; @@ -982,34 +950,15 @@ main(int argc, char *argv[]) */ if (!noop && rrdpon) { - if (socketpair(AF_UNIX, fl, 0, fd) == -1) - err(1, "socketpair"); - if ((rrdppid = fork()) == -1) - err(1, "fork"); - + rrdppid = process_start("rrdp", &fd); if (rrdppid == 0) { close(proc); close(rsync); close(http); - close(fd[1]); - - setproctitle("rrdp"); - /* change working directory to the cache directory */ - if (fchdir(cachefd) == -1) - err(1, "fchdir"); - - if (timeout) - alarm(timeout); - - if (pledge("stdio recvfd", NULL) == -1) - err(1, "pledge"); - - proc_rrdp(fd[0]); - /* NOTREACHED */ + proc_rrdp(fd); + errx(1, "rrdp process returned"); } - - close(fd[0]); - rrdp = fd[1]; + rrdp = fd; } else { rrdp = -1; rrdppid = -1; Index: parser.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v retrieving revision 1.66 diff -u -p -r1.66 parser.c --- parser.c 2 Apr 2022 12:17:53 -0000 1.66 +++ parser.c 11 Apr 2022 14:08:53 -0000 @@ -1219,6 +1219,12 @@ proc_parser(int fd) struct entity *entp; struct ibuf *b, *inbuf = NULL; + /* Only allow access to the cache directory. */ + if (unveil(".", "r") == -1) + err(1, "unveil cachedir"); + if (pledge("stdio rpath", NULL) == -1) + err(1, "pledge"); + ERR_load_crypto_strings(); OpenSSL_add_all_ciphers(); OpenSSL_add_all_digests(); Index: rsync.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/rsync.c,v retrieving revision 1.34 diff -u -p -r1.34 rsync.c --- rsync.c 4 Apr 2022 13:47:58 -0000 1.34 +++ rsync.c 11 Apr 2022 14:06:18 -0000 @@ -149,8 +149,10 @@ proc_rsync(char *prog, char *bind_addr, sigset_t mask, oldmask; struct rsyncproc ids[MAX_RSYNC_PROCESSES] = { 0 }; - pfd.fd = fd; + if (pledge("stdio rpath proc exec unveil", NULL) == -1) + err(1, "pledge"); + pfd.fd = fd; msgbuf_init(&msgq); msgq.fd = fd;