aboutsummaryrefslogtreecommitdiff
path: root/sandbox.c
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox.c')
-rw-r--r--sandbox.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/sandbox.c b/sandbox.c
new file mode 100644
index 0000000..f417e86
--- /dev/null
+++ b/sandbox.c
@@ -0,0 +1,113 @@
+#include "xs.h"
+
+#include "snac.h"
+
+#include <unistd.h>
+
+#if defined (__linux__)
+
+#define LL_PRINTERR(fmt, ...) srv_debug(0, xs_fmt(fmt, __VA_ARGS__))
+#include "landloc.h"
+
+static
+LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) {
+
+ const unsigned long long
+ rd = LANDLOCK_ACCESS_FS_READ_DIR,
+ rf = LANDLOCK_ACCESS_FS_READ_FILE,
+ w = LANDLOCK_ACCESS_FS_WRITE_FILE |
+ LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT,
+ c = LANDLOCK_ACCESS_FS_MAKE_DIR |
+ LANDLOCK_ACCESS_FS_MAKE_REG |
+ LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT |
+ LANDLOCK_ACCESS_FS_MAKE_SYM |
+ LANDLOCK_ACCESS_FS_REMOVE_DIR |
+ LANDLOCK_ACCESS_FS_REMOVE_FILE |
+ LANDLOCK_ACCESS_FS_REFER_COMPAT,
+ s = LANDLOCK_ACCESS_FS_MAKE_SOCK,
+ x = LANDLOCK_ACCESS_FS_EXECUTE;
+
+ LL_PATH(basedir, rf|rd|w|c);
+ LL_PATH("/tmp", rf|rd|w|c);
+#ifndef WITHOUT_SHM
+ LL_PATH("/dev/shm", rf|w|c );
+#endif
+ LL_PATH("/etc/resolv.conf", rf );
+ LL_PATH("/etc/hosts", rf );
+ LL_PATH("/etc/ssl/openssl.cnf", rf );
+ LL_PATH("/etc/ssl/cert.pem", rf );
+ LL_PATH("/usr/share/zoneinfo", rf );
+
+ if (*address == '/')
+ LL_PATH(address, s);
+
+ if (smail)
+ LL_PATH("/usr/sbin/sendmail", x);
+
+ if (*address != '/') {
+ unsigned short listen_port = xs_number_get(xs_dict_get(srv_config, "port"));
+ LL_PORT(listen_port, LANDLOCK_ACCESS_NET_BIND_TCP_COMPAT);
+ }
+
+ LL_PORT(80, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
+ LL_PORT(443, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
+
+} LL_END
+
+#endif
+
+void sbox_enter(const char *basedir)
+{
+ if (xs_is_true(xs_dict_get(srv_config, "disable_openbsd_security"))) {
+ srv_log(xs_dup("disable_openbsd_security is deprecated. Use disable_sandbox instead."));
+ return;
+ }
+ if (xs_is_true(xs_dict_get(srv_config, "disable_sandbox"))) {
+ srv_debug(0, xs_dup("Sandbox disabled by admin"));
+ return;
+ }
+
+ const char *address = xs_dict_get(srv_config, "address");
+
+ int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
+
+#if defined (__OpenBSD__)
+ srv_debug(1, xs_fmt("Calling unveil()"));
+ unveil(basedir, "rwc");
+ unveil("/tmp", "rwc");
+ unveil("/etc/resolv.conf", "r");
+ unveil("/etc/hosts", "r");
+ unveil("/etc/ssl/openssl.cnf", "r");
+ unveil("/etc/ssl/cert.pem", "r");
+ unveil("/usr/share/zoneinfo", "r");
+
+ if (smail)
+ unveil("/usr/sbin/sendmail", "x");
+
+ if (*address == '/')
+ unveil(address, "rwc");
+
+ unveil(NULL, NULL);
+
+ srv_debug(1, xs_fmt("Calling pledge()"));
+
+ xs *p = xs_str_new("stdio rpath wpath cpath flock inet proc dns fattr");
+
+ if (smail)
+ p = xs_str_cat(p, " exec");
+
+ if (*address == '/')
+ p = xs_str_cat(p, " unix");
+
+ pledge(p, NULL);
+
+ xs_free(p);
+#elif defined (__linux__)
+
+ if (sbox_enter_linux_(basedir, address, smail) == 0)
+ srv_log(xs_dup("landlocked"));
+ else
+ srv_log(xs_dup("landlocking failed"));
+
+#endif
+}