2.68 sandbox.c
  1#include "xs.h"
  2
  3#include "snac.h"
  4
  5#if defined(__OpenBSD__)
  6
  7void sbox_enter(const char *basedir)
  8{
  9    const char *address = xs_dict_get(srv_config, "address");
 10
 11    int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
 12
 13    if (xs_is_true(xs_dict_get(srv_config, "disable_openbsd_security"))) {
 14        srv_log(xs_dup("OpenBSD security disabled by admin"));
 15        return;
 16    }
 17
 18    srv_debug(1, xs_fmt("Calling unveil()"));
 19    unveil(basedir,                "rwc");
 20    unveil("/tmp",                 "rwc");
 21    unveil("/etc/resolv.conf",     "r");
 22    unveil("/etc/hosts",           "r");
 23    unveil("/etc/ssl/openssl.cnf", "r");
 24    unveil("/etc/ssl/cert.pem",    "r");
 25    unveil("/usr/share/zoneinfo",  "r");
 26
 27    if (smail)
 28        unveil("/usr/sbin/sendmail",   "x");
 29
 30    if (*address == '/')
 31        unveil(address, "rwc");
 32
 33    unveil(NULL,                   NULL);
 34
 35    srv_debug(1, xs_fmt("Calling pledge()"));
 36
 37    xs *p = xs_str_new("stdio rpath wpath cpath flock inet proc dns fattr");
 38
 39    if (smail)
 40        p = xs_str_cat(p, " exec");
 41
 42    if (*address == '/')
 43        p = xs_str_cat(p, " unix");
 44
 45    pledge(p, NULL);
 46}
 47
 48#elif defined(__linux__)
 49
 50#if defined(WITH_LINUX_SANDBOX)
 51
 52#include <unistd.h>
 53
 54#define LL_PRINTERR(fmt, ...) srv_debug(0, xs_fmt(fmt, __VA_ARGS__))
 55#include "landloc.h"
 56
 57static
 58LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) {
 59
 60    const unsigned long long
 61        rd = LANDLOCK_ACCESS_FS_READ_DIR,
 62        rf = LANDLOCK_ACCESS_FS_READ_FILE,
 63        w  = LANDLOCK_ACCESS_FS_WRITE_FILE      |
 64             LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT,
 65        c  = LANDLOCK_ACCESS_FS_MAKE_DIR        |
 66             LANDLOCK_ACCESS_FS_MAKE_REG        |
 67             LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT |
 68             LANDLOCK_ACCESS_FS_MAKE_SYM        |
 69             LANDLOCK_ACCESS_FS_REMOVE_DIR      |
 70             LANDLOCK_ACCESS_FS_REMOVE_FILE     |
 71             LANDLOCK_ACCESS_FS_REFER_COMPAT,
 72        s  = LANDLOCK_ACCESS_FS_MAKE_SOCK,
 73        x  = LANDLOCK_ACCESS_FS_EXECUTE;
 74
 75    LL_PATH(basedir,                rf|rd|w|c);
 76    LL_PATH("/tmp",                 rf|rd|w|c);
 77#ifndef WITHOUT_SHM
 78    LL_PATH("/dev/shm",             rf|w|c   );
 79#endif
 80    LL_PATH("/etc/resolv.conf",     rf       );
 81    LL_PATH("/etc/hosts",           rf       );
 82    LL_PATH("/etc/ssl",             rf       );
 83    LL_PATH("/usr/share/zoneinfo",  rf       );
 84
 85    if (mtime("/etc/pki") > 0)
 86        LL_PATH("/etc/pki",         rf       );
 87
 88    if (*address == '/') {
 89        /* the directory holding the socket must be allowed */
 90        xs *l = xs_split(address, "/");
 91        l = xs_list_del(l, -1);
 92        xs *sdir = xs_join(l, "/");
 93
 94        LL_PATH(sdir, s);
 95    }
 96
 97    if (smail && mtime("/usr/sbin/sendmail") > 0)
 98        LL_PATH("/usr/sbin/sendmail", x);
 99
100    if (*address != '/') {
101        unsigned short listen_port = xs_number_get(xs_dict_get(srv_config, "port"));
102        LL_PORT(listen_port, LANDLOCK_ACCESS_NET_BIND_TCP_COMPAT);
103    }
104
105    LL_PORT(80,  LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
106    LL_PORT(443, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
107
108} LL_END
109
110void sbox_enter(const char *basedir)
111{
112    const char *address = xs_dict_get(srv_config, "address");
113
114    int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
115
116    if (xs_is_true(xs_dict_get(srv_config, "disable_sandbox"))) {
117        srv_debug(1, xs_dup("Linux sandbox disabled by admin"));
118        return;
119    }
120
121    if (sbox_enter_linux_(basedir, address, smail) == 0)
122        srv_debug(1, xs_dup("Linux sandbox enabled"));
123    else
124        srv_debug(1, xs_dup("Linux sandbox failed"));
125}
126
127#else /* defined(WITH_LINUX_SANDBOX) */
128
129void sbox_enter(const char *basedir)
130{
131    (void)basedir;
132
133    srv_debug(1, xs_fmt("Linux sandbox not compiled in"));
134}
135
136#endif
137
138#else
139
140/* other OSs: dummy sbox_enter() */
141
142void sbox_enter(const char *basedir)
143{
144    (void)basedir;
145}
146
147
148#endif /* __OpenBSD__ */