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