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