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