From e52b4bf39b7236b2a89e34aaf5c54db2e2b285d8 Mon Sep 17 00:00:00 2001 From: shtrophic Date: Thu, 5 Dec 2024 17:24:04 +0100 Subject: import landloc.h --- sandbox.c | 173 ++++++++++++++++---------------------------------------------- 1 file changed, 44 insertions(+), 129 deletions(-) (limited to 'sandbox.c') diff --git a/sandbox.c b/sandbox.c index 7f26d0a..6dd9360 100644 --- a/sandbox.c +++ b/sandbox.c @@ -5,12 +5,49 @@ #include #if defined (__linux__) -# define __USE_GNU -# include -# include -# include -# include -# include + +#define LL_PRINTERR(fmt, ...) srv_debug(0, xs_fmt(fmt, __VA_ARGS__)) +#include "landloc.h" + +#define LL_R LANDLOCK_ACCESS_FS_READ_FILE +#define LL_X LANDLOCK_ACCESS_FS_EXECUTE +#define LL_RWCF (LL_R | LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_TRUNCATE | LANDLOCK_ACCESS_FS_REMOVE_FILE | LANDLOCK_ACCESS_FS_REFER) +#define LL_RWCD (LL_RWCF | LANDLOCK_ACCESS_FS_MAKE_DIR | LANDLOCK_ACCESS_FS_REMOVE_DIR) +#define LL_UNIX (LL_R | LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_MAKE_SOCK) +#define LL_CONN LANDLOCK_ACCESS_NET_CONNECT_TCP +#define LL_BIND LANDLOCK_ACCESS_NET_BIND_TCP + +static +LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) { + + LL_PATH(basedir, LL_RWCD); + LL_PATH("/tmp", LL_RWCD); +#ifndef WITHOUT_SHM + LL_PATH("/dev/shm", LL_RWCF); +#endif + LL_PATH("/etc/resolv.conf", LL_R ); + LL_PATH("/etc/hosts", LL_R ); + LL_PATH("/etc/ssl/openssl.cnf", LL_R ); + LL_PATH("/etc/ssl/cert.pem", LL_R ); + LL_PATH("/usr/share/zoneinfo", LL_R ); + + if (*address == '/') + LL_PATH(address, LL_UNIX); + + if (smail) + LL_PATH("/usr/sbin/sendmail", LL_X); + + + if (*address != '/') { + LL_PORT( + (unsigned short)xs_number_get(xs_dict_get(srv_config, "port")), LL_BIND); + } + + LL_PORT(80, LL_CONN); + LL_PORT(443, LL_CONN); + +} LL_END + #endif void sbox_enter(const char *basedir) @@ -60,132 +97,10 @@ void sbox_enter(const char *basedir) xs_free(p); #elif defined (__linux__) - int error, ruleset_fd, abi; - struct landlock_ruleset_attr rules = {0}; - struct landlock_path_beneath_attr path = {0}; - struct landlock_net_port_attr net = {0}; - - rules.handled_access_fs = - LANDLOCK_ACCESS_FS_EXECUTE | - LANDLOCK_ACCESS_FS_WRITE_FILE | - LANDLOCK_ACCESS_FS_READ_FILE | - LANDLOCK_ACCESS_FS_REMOVE_DIR | - LANDLOCK_ACCESS_FS_REMOVE_FILE | - LANDLOCK_ACCESS_FS_MAKE_CHAR | - LANDLOCK_ACCESS_FS_MAKE_DIR | - LANDLOCK_ACCESS_FS_MAKE_REG | - LANDLOCK_ACCESS_FS_MAKE_SOCK | - LANDLOCK_ACCESS_FS_MAKE_FIFO | - LANDLOCK_ACCESS_FS_MAKE_BLOCK | - LANDLOCK_ACCESS_FS_MAKE_SYM | - LANDLOCK_ACCESS_FS_REFER | - LANDLOCK_ACCESS_FS_TRUNCATE | - LANDLOCK_ACCESS_FS_IOCTL_DEV; - rules.handled_access_net = - LANDLOCK_ACCESS_NET_BIND_TCP | - LANDLOCK_ACCESS_NET_CONNECT_TCP; - - abi = syscall(SYS_landlock_create_ruleset, NULL, 0, LANDLOCK_CREATE_RULESET_VERSION); - switch (abi) { - case -1: - srv_debug(0, xs_dup("Kernel without landlock support")); - return; - case 1: - rules.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER; - __attribute__((fallthrough)); - case 2: - rules.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE; - __attribute__((fallthrough)); - case 3: - rules.handled_access_net &= ~(LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP); - __attribute__((fallthrough)); - case 4: - rules.handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV; - } - srv_debug(1, xs_fmt("lanlock abi: %d", abi)); - - ruleset_fd = syscall(SYS_landlock_create_ruleset, &rules, sizeof(struct landlock_ruleset_attr), 0); - if (ruleset_fd == -1) { - srv_debug(0, xs_fmt("landlock_create_ruleset failed: %s", strerror(errno))); - return; - } - -#define LL_R LANDLOCK_ACCESS_FS_READ_FILE -#define LL_X LANDLOCK_ACCESS_FS_EXECUTE -#define LL_RWCF (LL_R | LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_TRUNCATE | LANDLOCK_ACCESS_FS_REMOVE_FILE | LANDLOCK_ACCESS_FS_REFER) -#define LL_RWCD (LL_RWCF | LANDLOCK_ACCESS_FS_MAKE_DIR | LANDLOCK_ACCESS_FS_REMOVE_DIR) -#define LL_UNIX (LL_R | LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_MAKE_SOCK) -#define LL_CONN LANDLOCK_ACCESS_NET_CONNECT_TCP -#define LL_BIND LANDLOCK_ACCESS_NET_BIND_TCP - -#define LANDLOCK_PATH(p, r) do {\ - path.allowed_access = r;\ - if (abi < 2)\ - path.allowed_access &= ~LANDLOCK_ACCESS_FS_REFER;\ - if (abi < 3)\ - path.allowed_access &= ~LANDLOCK_ACCESS_FS_TRUNCATE;\ - path.parent_fd = open(p, O_PATH | O_CLOEXEC);\ - if (path.parent_fd == -1) {\ - srv_debug(2, xs_fmt("open %s: %s", p, strerror(errno)));\ - goto close;\ - }\ - error = syscall(SYS_landlock_add_rule, ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, &path, 0); \ - if (error) {\ - srv_debug(0, xs_fmt("LANDLOCK_PATH(%s): %s", p, strerror(errno)));\ - goto close;\ - }\ -} while (0) - -#define LANDLOCK_PORT(p, r) do {\ - uint16_t _p = p;\ - net.port = _p;\ - net.allowed_access = r;\ - error = syscall(SYS_landlock_add_rule, ruleset_fd, LANDLOCK_RULE_NET_PORT, &net, 0);\ - if (error) {\ - srv_debug(0, xs_fmt("LANDLOCK_PORT(%d): %s", _p, strerror(errno)));\ - goto close;\ - }\ -} while (0) - - LANDLOCK_PATH(basedir, LL_RWCD); - LANDLOCK_PATH("/tmp", LL_RWCD); -#ifndef WITHOUT_SHM - LANDLOCK_PATH("/dev/shm", LL_RWCF); -#endif - LANDLOCK_PATH("/etc/resolv.conf", LL_R ); - LANDLOCK_PATH("/etc/hosts", LL_R ); - LANDLOCK_PATH("/etc/ssl/openssl.cnf", LL_R ); - LANDLOCK_PATH("/etc/ssl/cert.pem", LL_R ); - LANDLOCK_PATH("/usr/share/zoneinfo", LL_R ); - - if (*address == '/') - LANDLOCK_PATH(address, LL_UNIX); - - if (smail) - LANDLOCK_PATH("/usr/sbin/sendmail", LL_X); - - if (abi > 3) { - if (*address != '/') { - LANDLOCK_PORT( - (uint16_t)xs_number_get(xs_dict_get(srv_config, "port")), LL_BIND); - } - - LANDLOCK_PORT(80, LL_CONN); - LANDLOCK_PORT(443, LL_CONN); - } - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { - srv_debug(0, xs_fmt("prctl SET_NO_NEW_PRIVS: %s", strerror(errno))); - goto close; - } - - if (syscall(SYS_landlock_restrict_self, ruleset_fd, 0)) - srv_debug(0, xs_fmt("landlock_restrict_self: %s", strerror(errno))); + sbox_enter_linux_(basedir, address, smail); srv_log(xs_dup("landlocked")); -close: - close(ruleset_fd); - #endif } -- cgit v1.2.3