summaryrefslogtreecommitdiff
path: root/sandbox.c
diff options
context:
space:
mode:
authorGravatar grunfink2025-01-05 12:16:27 +0000
committerGravatar grunfink2025-01-05 12:16:27 +0000
commitfced3aa3abae94c97d71ed60bd617c3de47a835d (patch)
tree204900c59f112272a759858e9b7641750f97c330 /sandbox.c
parentMoved post language setting to msg_note(), where it really belongs. (diff)
parentupdate landloc.h (diff)
downloadpenes-snac2-fced3aa3abae94c97d71ed60bd617c3de47a835d.tar.gz
penes-snac2-fced3aa3abae94c97d71ed60bd617c3de47a835d.tar.xz
penes-snac2-fced3aa3abae94c97d71ed60bd617c3de47a835d.zip
Merge pull request 'Port sandboxing to linux via landlock' (#226) from shtrophic/snac2:master into master
Reviewed-on: https://codeberg.org/grunfink/snac2/pulls/226
Diffstat (limited to '')
-rw-r--r--sandbox.c113
1 files changed, 113 insertions, 0 deletions
diff --git a/sandbox.c b/sandbox.c
new file mode 100644
index 0000000..f417e86
--- /dev/null
+++ b/sandbox.c
@@ -0,0 +1,113 @@
1#include "xs.h"
2
3#include "snac.h"
4
5#include <unistd.h>
6
7#if defined (__linux__)
8
9#define LL_PRINTERR(fmt, ...) srv_debug(0, xs_fmt(fmt, __VA_ARGS__))
10#include "landloc.h"
11
12static
13LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) {
14
15 const unsigned long long
16 rd = LANDLOCK_ACCESS_FS_READ_DIR,
17 rf = LANDLOCK_ACCESS_FS_READ_FILE,
18 w = LANDLOCK_ACCESS_FS_WRITE_FILE |
19 LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT,
20 c = LANDLOCK_ACCESS_FS_MAKE_DIR |
21 LANDLOCK_ACCESS_FS_MAKE_REG |
22 LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT |
23 LANDLOCK_ACCESS_FS_MAKE_SYM |
24 LANDLOCK_ACCESS_FS_REMOVE_DIR |
25 LANDLOCK_ACCESS_FS_REMOVE_FILE |
26 LANDLOCK_ACCESS_FS_REFER_COMPAT,
27 s = LANDLOCK_ACCESS_FS_MAKE_SOCK,
28 x = LANDLOCK_ACCESS_FS_EXECUTE;
29
30 LL_PATH(basedir, rf|rd|w|c);
31 LL_PATH("/tmp", rf|rd|w|c);
32#ifndef WITHOUT_SHM
33 LL_PATH("/dev/shm", rf|w|c );
34#endif
35 LL_PATH("/etc/resolv.conf", rf );
36 LL_PATH("/etc/hosts", rf );
37 LL_PATH("/etc/ssl/openssl.cnf", rf );
38 LL_PATH("/etc/ssl/cert.pem", rf );
39 LL_PATH("/usr/share/zoneinfo", rf );
40
41 if (*address == '/')
42 LL_PATH(address, s);
43
44 if (smail)
45 LL_PATH("/usr/sbin/sendmail", x);
46
47 if (*address != '/') {
48 unsigned short listen_port = xs_number_get(xs_dict_get(srv_config, "port"));
49 LL_PORT(listen_port, LANDLOCK_ACCESS_NET_BIND_TCP_COMPAT);
50 }
51
52 LL_PORT(80, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
53 LL_PORT(443, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
54
55} LL_END
56
57#endif
58
59void sbox_enter(const char *basedir)
60{
61 if (xs_is_true(xs_dict_get(srv_config, "disable_openbsd_security"))) {
62 srv_log(xs_dup("disable_openbsd_security is deprecated. Use disable_sandbox instead."));
63 return;
64 }
65 if (xs_is_true(xs_dict_get(srv_config, "disable_sandbox"))) {
66 srv_debug(0, xs_dup("Sandbox disabled by admin"));
67 return;
68 }
69
70 const char *address = xs_dict_get(srv_config, "address");
71
72 int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
73
74#if defined (__OpenBSD__)
75 srv_debug(1, xs_fmt("Calling unveil()"));
76 unveil(basedir, "rwc");
77 unveil("/tmp", "rwc");
78 unveil("/etc/resolv.conf", "r");
79 unveil("/etc/hosts", "r");
80 unveil("/etc/ssl/openssl.cnf", "r");
81 unveil("/etc/ssl/cert.pem", "r");
82 unveil("/usr/share/zoneinfo", "r");
83
84 if (smail)
85 unveil("/usr/sbin/sendmail", "x");
86
87 if (*address == '/')
88 unveil(address, "rwc");
89
90 unveil(NULL, NULL);
91
92 srv_debug(1, xs_fmt("Calling pledge()"));
93
94 xs *p = xs_str_new("stdio rpath wpath cpath flock inet proc dns fattr");
95
96 if (smail)
97 p = xs_str_cat(p, " exec");
98
99 if (*address == '/')
100 p = xs_str_cat(p, " unix");
101
102 pledge(p, NULL);
103
104 xs_free(p);
105#elif defined (__linux__)
106
107 if (sbox_enter_linux_(basedir, address, smail) == 0)
108 srv_log(xs_dup("landlocked"));
109 else
110 srv_log(xs_dup("landlocking failed"));
111
112#endif
113}