2.74 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    char *resolved_path = NULL;
 75
 76    LL_PATH(basedir,                rf|rd|w|c);
 77    LL_PATH("/tmp",                 rf|rd|w|c);
 78#ifndef WITHOUT_SHM
 79    LL_PATH("/dev/shm",             rf|w|c   );
 80#endif
 81    LL_PATH("/dev/urandom",         rf       );
 82    LL_PATH("/etc/resolv.conf",     rf       );
 83    LL_PATH("/etc/hosts",           rf       );
 84    LL_PATH("/etc/ssl",             rf|rd    );
 85    if ((resolved_path = realpath("/etc/ssl/cert.pem", NULL))) {
 86        /* some distros like cert.pem to be a symlink */
 87        LL_PATH(resolved_path,      rf       );
 88        free(resolved_path);
 89    }
 90    LL_PATH("/usr/share/zoneinfo",  rf       );
 91
 92    if (mtime("/etc/pki") > 0)
 93        LL_PATH("/etc/pki",         rf       );
 94
 95    if (*address == '/') {
 96        /* the directory holding the socket must be allowed */
 97        xs *l = xs_split(address, "/");
 98        l = xs_list_del(l, -1);
 99        xs *sdir = xs_join(l, "/");
100
101        LL_PATH(sdir, s);
102    }
103
104    if (smail && mtime("/usr/sbin/sendmail") > 0)
105        LL_PATH("/usr/sbin/sendmail", x);
106
107    if (*address != '/') {
108        unsigned short listen_port = xs_number_get(xs_dict_get(srv_config, "port"));
109        LL_PORT(listen_port, LANDLOCK_ACCESS_NET_BIND_TCP_COMPAT);
110    }
111
112    LL_PORT(80,  LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
113    LL_PORT(443, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
114
115} LL_END
116
117void sbox_enter(const char *basedir)
118{
119    const char *address = xs_dict_get(srv_config, "address");
120
121    int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
122
123    if (xs_is_true(xs_dict_get(srv_config, "disable_sandbox"))) {
124        srv_debug(1, xs_dup("Linux sandbox disabled by admin"));
125        return;
126    }
127
128    if (sbox_enter_linux_(basedir, address, smail) == 0)
129        srv_debug(1, xs_dup("Linux sandbox enabled"));
130    else
131        srv_debug(1, xs_dup("Linux sandbox failed"));
132}
133
134#else /* defined(WITH_LINUX_SANDBOX) */
135
136void sbox_enter(const char *basedir)
137{
138    (void)basedir;
139
140    srv_debug(1, xs_fmt("Linux sandbox not compiled in"));
141}
142
143#endif
144
145#else
146
147/* other OSs: dummy sbox_enter() */
148
149void sbox_enter(const char *basedir)
150{
151    (void)basedir;
152}
153
154
155#endif /* __OpenBSD__ */