if (str2num(strport, &port)) {
fprintf(stderr, "Failed to parse port at \"%s\"\n",
strport); goto out_free_name;
}
net_port.port = port; if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
&net_port, 0)) {
fprintf(stderr, "Failed to update the ruleset with port \"%llu\": %s\n",
net_port.port, strerror(errno)); goto out_free_name;
}
}
ret = 0;
/* Scoping is not supported by Landlock ABI */ if (!(ruleset_attr->scoped &
(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL))) goto out_unset;
env_type_scope = getenv(env_var); /* Scoping is not supported by the user */ if (!env_type_scope || strcmp("", env_type_scope) == 0) goto out_unset;
staticconstchar help[] = "usage: " ENV_FS_RO_NAME "=\"...\" " ENV_FS_RW_NAME "=\"...\" " "[other environment variables] %1$s [args]...\n" "\n" "Execute the given command in a restricted environment.\n" "Multi-valued settings (lists of ports, paths, scopes) are colon-delimited.\n" "\n" "Mandatory settings:\n" "* " ENV_FS_RO_NAME ": paths allowed to be used in a read-only way\n" "* " ENV_FS_RW_NAME ": paths allowed to be used in a read-write way\n" "\n" "Optional settings (when not set, their associated access check " "is always allowed, which is different from an empty string which " "means an empty list):\n" "* " ENV_TCP_BIND_NAME ": ports allowed to bind (server)\n" "* " ENV_TCP_CONNECT_NAME ": ports allowed to connect (client)\n" "* " ENV_SCOPED_NAME ": actions denied on the outside of the landlock domain\n" " - \"a\" to restrict opening abstract unix sockets\n" " - \"s\" to restrict sending signals\n" "\n" "A sandboxer should not log denied access requests to avoid spamming logs, " "but to test audit we can set " ENV_FORCE_LOG_NAME "=1\n" "\n" "Example:\n"
ENV_FS_RO_NAME "=\"${PATH}:/lib:/usr:/proc:/etc:/dev/urandom\" "
ENV_FS_RW_NAME "=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" "
ENV_TCP_BIND_NAME "=\"9418\" "
ENV_TCP_CONNECT_NAME "=\"80:443\" "
ENV_SCOPED_NAME "=\"a:s\" " "%1$s bash -i\n" "\n" "This sandboxer can use Landlock features up to ABI version "
STR(LANDLOCK_ABI_LAST) ".\n";
abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION); if (abi < 0) { constint err = errno;
perror("Failed to check Landlock compatibility"); switch (err) { case ENOSYS:
fprintf(stderr, "Hint: Landlock is not supported by the current kernel. " "To support it, build the kernel with " "CONFIG_SECURITY_LANDLOCK=y and prepend " "\"landlock,\" to the content of CONFIG_LSM.\n"); break; case EOPNOTSUPP:
fprintf(stderr, "Hint: Landlock is currently disabled. " "It can be enabled in the kernel configuration by " "prepending \"landlock,\" to the content of CONFIG_LSM, " "or at boot time by setting the same content to the " "\"lsm\" kernel parameter.\n"); break;
} return 1;
}
/* Best-effort security. */ switch (abi) { case 1: /* * Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 * * Note: The "refer" operations (file renaming and linking * across different directories) are always forbidden when using * Landlock with ABI 1. * * If only ABI 1 is available, this sandboxer knowingly forbids * refer operations. * * If a program *needs* to do refer operations after enabling * Landlock, it can not use Landlock at ABI level 1. To be * compatible with different kernel versions, such programs * should then fall back to not restrict themselves at all if * the running kernel only supports ABI 1.
*/
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
__attribute__((fallthrough)); case 2: /* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
__attribute__((fallthrough)); case 3: /* Removes network support for ABI < 4 */
ruleset_attr.handled_access_net &=
~(LANDLOCK_ACCESS_NET_BIND_TCP |
LANDLOCK_ACCESS_NET_CONNECT_TCP);
__attribute__((fallthrough)); case 4: /* Removes LANDLOCK_ACCESS_FS_IOCTL_DEV for ABI < 5 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_IOCTL_DEV;
__attribute__((fallthrough)); case 5: /* Removes LANDLOCK_SCOPE_* for ABI < 6 */
ruleset_attr.scoped &= ~(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
LANDLOCK_SCOPE_SIGNAL);
__attribute__((fallthrough)); case 6: /* Removes LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON for ABI < 7 */
supported_restrict_flags &=
~LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON;
/* Must be printed for any ABI < LANDLOCK_ABI_LAST. */
fprintf(stderr, "Hint: You should update the running kernel " "to leverage Landlock features " "provided by ABI version %d (instead of %d).\n",
LANDLOCK_ABI_LAST, abi);
__attribute__((fallthrough)); case LANDLOCK_ABI_LAST: break; default:
fprintf(stderr, "Hint: You should update this sandboxer " "to leverage Landlock features " "provided by ABI version %d (instead of %d).\n",
abi, LANDLOCK_ABI_LAST);
}
access_fs_ro &= ruleset_attr.handled_access_fs;
access_fs_rw &= ruleset_attr.handled_access_fs;
/* Removes bind access attribute if not supported by a user. */
env_port_name = getenv(ENV_TCP_BIND_NAME); if (!env_port_name) {
ruleset_attr.handled_access_net &=
~LANDLOCK_ACCESS_NET_BIND_TCP;
} /* Removes connect access attribute if not supported by a user. */
env_port_name = getenv(ENV_TCP_CONNECT_NAME); if (!env_port_name) {
ruleset_attr.handled_access_net &=
~LANDLOCK_ACCESS_NET_CONNECT_TCP;
}
if (check_ruleset_scope(ENV_SCOPED_NAME, &ruleset_attr)) return 1;
/* Enables optional logs. */
env_force_log = getenv(ENV_FORCE_LOG_NAME); if (env_force_log) { if (strcmp(env_force_log, "1") != 0) {
fprintf(stderr, "Unknown value for " ENV_FORCE_LOG_NAME " (only \"1\" is handled)\n"); return 1;
} if (!(supported_restrict_flags &
LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON)) {
fprintf(stderr, "Audit logs not supported by current kernel\n"); return 1;
}
set_restrict_flags |= LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON;
unsetenv(ENV_FORCE_LOG_NAME);
}
ruleset_fd =
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); if (ruleset_fd < 0) {
perror("Failed to create a ruleset"); return 1;
}
if (populate_ruleset_fs(ENV_FS_RO_NAME, ruleset_fd, access_fs_ro)) { goto err_close_ruleset;
} if (populate_ruleset_fs(ENV_FS_RW_NAME, ruleset_fd, access_fs_rw)) { goto err_close_ruleset;
}
if (populate_ruleset_net(ENV_TCP_BIND_NAME, ruleset_fd,
LANDLOCK_ACCESS_NET_BIND_TCP)) { goto err_close_ruleset;
} if (populate_ruleset_net(ENV_TCP_CONNECT_NAME, ruleset_fd,
LANDLOCK_ACCESS_NET_CONNECT_TCP)) { goto err_close_ruleset;
}
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
perror("Failed to restrict privileges"); goto err_close_ruleset;
} if (landlock_restrict_self(ruleset_fd, set_restrict_flags)) {
perror("Failed to enforce ruleset"); goto err_close_ruleset;
}
close(ruleset_fd);
cmd_path = argv[1];
cmd_argv = argv + 1;
fprintf(stderr, "Executing the sandboxed command...\n");
execvpe(cmd_path, cmd_argv, envp);
fprintf(stderr, "Failed to execute \"%s\": %s\n", cmd_path,
strerror(errno));
fprintf(stderr, "Hint: access to the binary, the interpreter or " "shared libraries may be denied.\n"); return 1;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.