1 #include "../../system.h"
7 #include "../../device.h"
8 #include "../../logger.h"
9 #include "../../names.h"
10 #include "../../net.h"
11 #include "../../sandbox.h"
12 #include "../../script.h"
13 #include "../../xalloc.h"
14 #include "../../proxy.h"
16 static sandbox_level_t current_level = SANDBOX_NONE;
17 static bool can_use_new_paths = true;
18 static bool entered = false;
20 static bool chrooted(void) {
21 return !(confbase && *confbase);
24 static void open_conf_subdir(const char *name, const char *privs) {
26 snprintf(path, sizeof(path), "%s/%s", confbase, name);
27 allow_path(path, privs);
30 static void open_common_paths(bool can_exec) {
31 // Dummy device uses a fake path, skip it
32 const char *dev = strcasecmp(device, DEVICE_DUMMY) ? device : NULL;
34 const unveil_path_t paths[] = {
36 {"/dev/urandom", "r"},
37 {confbase, can_exec ? "rx" : "r"},
41 {unixsocketname, "rwc"},
46 open_conf_subdir("cache", "rwc");
47 open_conf_subdir("hosts", can_exec ? "rwxc" : "rwc");
48 open_conf_subdir("invitations", "rwc");
51 static void open_exec_paths(void) {
52 // proxyhost was checked previously. If we're here, proxyhost
53 // contains the path to the executable, and nothing else.
54 const char *proxy_exec = proxytype == PROXY_EXEC ? proxyhost : NULL;
56 const unveil_path_t bin_paths[] = {
61 {"/usr/local/bin", "rx"},
62 {"/usr/local/sbin", "rx"},
63 {scriptinterpreter, "rx"},
67 allow_paths(bin_paths);
70 static bool sandbox_privs(bool can_exec) {
71 // no mcast since multicasting should be set up by now
73 "stdio" // General I/O, both disk and network
74 " rpath" // Read files and directories
75 " wpath" // Write files and directories
76 " cpath" // Create new ones
77 " dns" // Resolve domain names
78 " inet" // Make network connections
79 " unix"; // Control socket connections from tinc CLI
82 // fork() and execve() for scripts and exec proxies
83 const char *exec = " proc exec";
84 size_t n = strlcat(promises, exec, sizeof(promises));
85 assert(n < sizeof(promises));
88 return restrict_privs(promises, can_exec ? PROMISES_ALL : PROMISES_NONE);
91 static void sandbox_paths(bool can_exec) {
93 logger(DEBUG_ALWAYS, LOG_DEBUG, "chroot is used. Disabling path sandbox.");
97 open_common_paths(can_exec);
98 can_use_new_paths = false;
101 if(proxytype == PROXY_EXEC && !access(proxyhost, X_OK)) {
102 logger(DEBUG_ALWAYS, LOG_WARNING, "Looks like a shell expression was used for exec proxy. Using weak path sandbox.");
103 allow_path("/", "rx");
110 static bool sandbox_can_after_enter(sandbox_action_t action) {
112 case START_PROCESSES:
113 return current_level < SANDBOX_HIGH;
116 return can_use_new_paths;
123 bool sandbox_can(sandbox_action_t action, sandbox_time_t when) {
124 if(when == AFTER_SANDBOX || entered) {
125 return sandbox_can_after_enter(action);
131 void sandbox_set_level(sandbox_level_t level) {
133 current_level = level;
136 bool sandbox_enter() {
140 if(current_level == SANDBOX_NONE) {
141 logger(DEBUG_ALWAYS, LOG_DEBUG, "Sandbox is disabled");
145 bool can_exec = sandbox_can_after_enter(START_PROCESSES);
147 sandbox_paths(can_exec);
149 if(sandbox_privs(can_exec)) {
150 logger(DEBUG_ALWAYS, LOG_DEBUG, "Entered sandbox at level %d", current_level);
154 logger(DEBUG_ALWAYS, LOG_ERR, "Could not enter sandbox. Set a lower level or disable it in tinc.conf");
155 current_level = SANDBOX_NONE;