summaryrefslogtreecommitdiff
path: root/samples
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-09-24 10:40:11 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2024-09-24 10:40:11 -0700
commite1b061b444fb01c237838f0d8238653afe6a8094 (patch)
treea98ecdbdd1d490c1611073d886586a288f3ed498 /samples
parent24f772dec31591f9268a9c9e4943dc5dc47eaf9b (diff)
parent1ca980815e1f284dddcb5e678c91bbd3e3f3a6a6 (diff)
Merge tag 'landlock-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux
Pull landlock updates from Mickaël Salaün: "We can now scope a Landlock domain thanks to a new "scoped" field that can deny interactions with resources outside of this domain. The LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET flag denies connections to an abstract UNIX socket created outside of the current scoped domain, and the LANDLOCK_SCOPE_SIGNAL flag denies sending a signal to processes outside of the current scoped domain. These restrictions also apply to nested domains according to their scope. The related changes will also be useful to support other kind of IPC isolations" * tag 'landlock-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux: landlock: Document LANDLOCK_SCOPE_SIGNAL samples/landlock: Add support for signal scoping selftests/landlock: Test signal created by out-of-bound message selftests/landlock: Test signal scoping for threads selftests/landlock: Test signal scoping landlock: Add signal scoping landlock: Document LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET samples/landlock: Add support for abstract UNIX socket scoping selftests/landlock: Test inherited restriction of abstract UNIX socket selftests/landlock: Test connected and unconnected datagram UNIX socket selftests/landlock: Test UNIX sockets with any address formats selftests/landlock: Test abstract UNIX socket scoping selftests/landlock: Test handling of unknown scope landlock: Add abstract UNIX socket scoping
Diffstat (limited to 'samples')
-rw-r--r--samples/landlock/sandboxer.c73
1 files changed, 69 insertions, 4 deletions
diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c
index e8223c3e781a..f847e832ba14 100644
--- a/samples/landlock/sandboxer.c
+++ b/samples/landlock/sandboxer.c
@@ -14,6 +14,7 @@
#include <fcntl.h>
#include <linux/landlock.h>
#include <linux/prctl.h>
+#include <linux/socket.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -22,6 +23,7 @@
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>
+#include <stdbool.h>
#ifndef landlock_create_ruleset
static inline int
@@ -55,6 +57,7 @@ static inline int landlock_restrict_self(const int ruleset_fd,
#define ENV_FS_RW_NAME "LL_FS_RW"
#define ENV_TCP_BIND_NAME "LL_TCP_BIND"
#define ENV_TCP_CONNECT_NAME "LL_TCP_CONNECT"
+#define ENV_SCOPED_NAME "LL_SCOPED"
#define ENV_DELIMITER ":"
static int parse_path(char *env_path, const char ***const path_list)
@@ -184,6 +187,55 @@ out_free_name:
return ret;
}
+/* Returns true on error, false otherwise. */
+static bool check_ruleset_scope(const char *const env_var,
+ struct landlock_ruleset_attr *ruleset_attr)
+{
+ char *env_type_scope, *env_type_scope_next, *ipc_scoping_name;
+ bool error = false;
+ bool abstract_scoping = false;
+ bool signal_scoping = false;
+
+ /* 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;
+
+ env_type_scope = strdup(env_type_scope);
+ env_type_scope_next = env_type_scope;
+ while ((ipc_scoping_name =
+ strsep(&env_type_scope_next, ENV_DELIMITER))) {
+ if (strcmp("a", ipc_scoping_name) == 0 && !abstract_scoping) {
+ abstract_scoping = true;
+ } else if (strcmp("s", ipc_scoping_name) == 0 &&
+ !signal_scoping) {
+ signal_scoping = true;
+ } else {
+ fprintf(stderr, "Unknown or duplicate scope \"%s\"\n",
+ ipc_scoping_name);
+ error = true;
+ goto out_free_name;
+ }
+ }
+
+out_free_name:
+ free(env_type_scope);
+
+out_unset:
+ if (!abstract_scoping)
+ ruleset_attr->scoped &= ~LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET;
+ if (!signal_scoping)
+ ruleset_attr->scoped &= ~LANDLOCK_SCOPE_SIGNAL;
+
+ unsetenv(env_var);
+ return error;
+}
+
/* clang-format off */
#define ACCESS_FS_ROUGHLY_READ ( \
@@ -208,7 +260,7 @@ out_free_name:
/* clang-format on */
-#define LANDLOCK_ABI_LAST 5
+#define LANDLOCK_ABI_LAST 6
int main(const int argc, char *const argv[], char *const *const envp)
{
@@ -223,14 +275,16 @@ int main(const int argc, char *const argv[], char *const *const envp)
.handled_access_fs = access_fs_rw,
.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
LANDLOCK_ACCESS_NET_CONNECT_TCP,
+ .scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
+ LANDLOCK_SCOPE_SIGNAL,
};
if (argc < 2) {
fprintf(stderr,
- "usage: %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\"%s "
+ "usage: %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\" %s=\"...\" %s "
"<cmd> [args]...\n\n",
ENV_FS_RO_NAME, ENV_FS_RW_NAME, ENV_TCP_BIND_NAME,
- ENV_TCP_CONNECT_NAME, argv[0]);
+ ENV_TCP_CONNECT_NAME, ENV_SCOPED_NAME, argv[0]);
fprintf(stderr,
"Execute a command in a restricted environment.\n\n");
fprintf(stderr,
@@ -251,15 +305,18 @@ int main(const int argc, char *const argv[], char *const *const envp)
fprintf(stderr,
"* %s: list of ports allowed to connect (client).\n",
ENV_TCP_CONNECT_NAME);
+ fprintf(stderr, "* %s: list of scoped IPCs.\n",
+ ENV_SCOPED_NAME);
fprintf(stderr,
"\nexample:\n"
"%s=\"${PATH}:/lib:/usr:/proc:/etc:/dev/urandom\" "
"%s=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" "
"%s=\"9418\" "
"%s=\"80:443\" "
+ "%s=\"a:s\" "
"%s bash -i\n\n",
ENV_FS_RO_NAME, ENV_FS_RW_NAME, ENV_TCP_BIND_NAME,
- ENV_TCP_CONNECT_NAME, argv[0]);
+ ENV_TCP_CONNECT_NAME, ENV_SCOPED_NAME, argv[0]);
fprintf(stderr,
"This sandboxer can use Landlock features "
"up to ABI version %d.\n",
@@ -327,6 +384,11 @@ int main(const int argc, char *const argv[], char *const *const envp)
/* 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);
fprintf(stderr,
"Hint: You should update the running kernel "
"to leverage Landlock features "
@@ -358,6 +420,9 @@ int main(const int argc, char *const argv[], char *const *const envp)
~LANDLOCK_ACCESS_NET_CONNECT_TCP;
}
+ if (check_ruleset_scope(ENV_SCOPED_NAME, &ruleset_attr))
+ return 1;
+
ruleset_fd =
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
if (ruleset_fd < 0) {