From df280aa7d658163adae378b468db6fe884bbe02e Mon Sep 17 00:00:00 2001 From: C. McEnroe Date: Sun, 10 Jan 2021 19:23:01 -0500 Subject: Sandbox with unveil(2) on OpenBSD in restricted mode I wrote all this in vi and it was nice. --- chat.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 5 deletions(-) diff --git a/chat.c b/chat.c index 3f020fd..b4458be 100644 --- a/chat.c +++ b/chat.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "chat.h" @@ -123,6 +124,54 @@ static void parseHash(char *str) { if (*str) hashBound = strtoul(&str[1], NULL, 0); } +#ifdef __OpenBSD__ + +static void unveilConfig(const char *name) { + const char *dirs = NULL; + for (const char *path; NULL != (path = configPath(&dirs, name));) { + int error = unveil(path, "r"); + if (error && errno != ENOENT) err(EX_NOINPUT, "%s", path); + } +} + +static void unveilData(const char *name) { + const char *dirs = NULL; + for (const char *path; NULL != (path = dataPath(&dirs, name));) { + int error = unveil(path, "rwc"); + if (error && errno != ENOENT) err(EX_CANTCREAT, "%s", path); + } +} + +static void sandbox(const char *trust, const char *cert, const char *priv) { + int error = pledge( + "stdio rpath wpath cpath inet dns tty proc exec unveil", NULL + ); + if (error) err(EX_OSERR, "pledge"); + if (!self.restricted) return; + + dataMkdir(""); + unveilData(""); + if (trust) unveilConfig(trust); + if (cert) unveilConfig(cert); + if (priv) unveilConfig(priv); + if (save) unveilData(save); + struct { + const char *path; + const char *perm; + } paths[] = { + { "/usr/bin/man", "x" }, + { "/usr/share/terminfo", "r" }, + { tls_default_ca_cert_file(), "r" }, + { NULL, NULL }, + }; + for (size_t i = 0; i < ARRAY_LEN(paths); ++i) { + int error = unveil(paths[i].path, paths[i].perm); + if (error) err(EX_OSFILE, "%s", paths[i].path); + } +} + +#endif /* __OpenBSD__ */ + static volatile sig_atomic_t signals[NSIG]; static void signalHandler(int signal) { signals[signal] = 1; @@ -131,11 +180,6 @@ static void signalHandler(int signal) { int main(int argc, char *argv[]) { setlocale(LC_CTYPE, ""); -#ifdef __OpenBSD__ - int error = pledge("stdio rpath wpath cpath inet dns tty proc exec", NULL); - if (error) err(EX_OSERR, "pledge"); -#endif - bool insecure = false; bool printCert = false; const char *bind = NULL; @@ -237,6 +281,10 @@ int main(int argc, char *argv[]) { editCompleteAdd(); commandCompleteAdd(); +#ifdef __OpenBSD__ + sandbox(trust, cert, priv); +#endif + ircConfig(insecure, trust, cert, priv); if (printCert) { ircConnect(bind, host, port); -- cgit 1.4.1-2-gfad0