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