commit 623876e175a9cf09a7b7ab0a3985568c9b2ccd4c from: Niko Nastonen date: Mon Oct 5 20:15:56 2026 UTC Removed droppriv() and setuid commit - d33ca522cdea5d420643c2c92a67db48764a0fc4 commit + 623876e175a9cf09a7b7ab0a3985568c9b2ccd4c blob - 3a6e8b483b30f62b49005802d2f385998ec37933 blob + 6784fedcebbb5db7098941123eb6c458f50cb51d --- Makefile +++ Makefile @@ -7,8 +7,5 @@ LDADD= -lcrypto -lutil DPADD= ${LIBCRYPTO} ${LIBUTIL} BINDIR= /usr/local/bin -BINOWN= nobody -BINGRP= nobody -BINMODE=6555 .include blob - 2cf1a309829ca5ed8bb8eb9ac2f138fc5f878f97 blob + 3982f1c40bea3e8c22ae322eb71aee6849e3b6d7 --- ochat.c +++ ochat.c @@ -6,12 +6,7 @@ * Both sides run "ochat peer-address". Each tries to connect once: * if the peer is not up yet, it listens instead and accepts only the * peer. One process, one TCP connection, no files, no logs. Pledges - * down to "stdio tty" before any byte from the peer is parsed. - * - * Always runs as nobody, whoever starts it: install it setuid and - * setgid nobody (mode 6555), and the very first thing it does is - * set real, effective and saved ids to nobody. Started as root, it - * also chroots to /var/empty and drops supplementary groups. + * down to "stdio" before any byte from the peer is parsed. */ #include @@ -26,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -47,7 +41,6 @@ static uint8_t *pass; /* concealed, PASSMAX bytes */ static void cleanup(void); static void sighandler(int); -static void droppriv(void); static int netconnect(const struct sockaddr_in *); static int netaccept(const struct sockaddr_in *); static size_t readpass(void); @@ -73,8 +66,6 @@ main(int argc, char *argv[]) int ch, init, on = 1, port = PORT, s; size_t passlen; - droppriv(); - while ((ch = getopt(argc, argv, "lp:")) != -1) { switch (ch) { case 'p': @@ -131,7 +122,7 @@ main(int argc, char *argv[]) err(1, "setsockopt"); fprintf(stderr, "connected to %s\n", argv[0]); - if (pledge("stdio tty", NULL) == -1) + if (pledge("stdio", NULL) == -1) err(1, "pledge"); proto_handshake(s, init, pass, passlen, sas, sizeof(sas)); @@ -179,47 +170,6 @@ sighandler(int sig) _exit(128 + sig); } -/* - * Become nobody for good. From a setuid/setgid nobody binary the - * effective and saved ids already are nobody, so an unprivileged - * setresuid/setresgid may copy them into the real ids too. Root - * can do it outright, plus chroot and setgroups. - */ -static void -droppriv(void) -{ - struct passwd *pw; - uid_t uid; - gid_t gid; - - if ((pw = getpwnam("nobody")) == NULL) - errx(1, "no such user: nobody"); - uid = pw->pw_uid; - gid = pw->pw_gid; - - if (geteuid() == 0) { - if (chroot("/var/empty") == -1 || chdir("/") == -1) - err(1, "chroot"); - if (setgroups(1, &gid) == -1) - err(1, "setgroups"); - } else if (geteuid() != uid) { - errx(1, "Not running as nobody: the setuid bit was ignored. " - "Install under /usr/local (doas make install) and run it " - "from there; /home, /tmp, and /var are mounted nosuid."); - } - - if (setresgid(gid, gid, gid) == -1 || setresuid(uid, uid, uid) == -1) - errx(1, "cannot become nobody: install ochat setuid and " - "setgid nobody (chown nobody:nobody, chmod 6555)"); - - if (getuid() != uid || geteuid() != uid || getgid() != gid || getegid() != gid) - errx(1, "failed to become nobody"); - - /* We do pledge, which grants no file access at all, later, but still. */ - if (unveil("/", "") == -1 || unveil(NULL, NULL) == -1) - err(1, "unveil"); -} - /* Try once. Refused means the peer is not up yet: return -1. */ static int netconnect(const struct sockaddr_in *peer)