2.72
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__ */