Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate runtime components into single runtime #290

Merged
merged 18 commits into from
Jan 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
ab0ae4b
runtime: move landlock.h to landlock_syscall.h
fw-immunant Sep 25, 2023
659248a
runtime: split landlock functionality out of demo main
fw-immunant Sep 25, 2023
8c6e4f7
runtime: rename seccomp_filter.c to seccomp_filter_demo.c
fw-immunant Sep 25, 2023
8746280
runtime/seccomp_demo: fix program name in usage comment
fw-immunant Nov 1, 2023
963734e
runtime: split seccomp functionality out of seccomp demo
fw-immunant Sep 25, 2023
3a88aee
runtime/track_memory_map: track inferior exit status
fw-immunant Sep 25, 2023
0a14415
runtime/track_memory_map_demo: cleanups and comments
fw-immunant Oct 18, 2023
51ffc32
runtime/seccomp_filter: accept program as argument
fw-immunant Sep 25, 2023
cc3f008
runtime/seccomp_filter: normalize comment syntax
fw-immunant Sep 25, 2023
88ce00a
runtime/seccomp_filter: wrap seccomp()
fw-immunant Sep 25, 2023
3d96a8e
runtime/seccomp_filter: use RET_KILL_PROCESS, not RET_KILL
fw-immunant Oct 18, 2023
edff2b6
runtime/seccomp_filter: add filter program for IA2 coarse-grained sys…
fw-immunant Sep 25, 2023
39337d3
runtime/start: add IA2 runtime wrapper
fw-immunant Sep 25, 2023
e9f0ade
runtime/track_memory_map: distinguish between seccomp and ptrace modes
fw-immunant Oct 18, 2023
c1e1956
runtime/seccomp_filter: allow dup/dup2/fcntl
fw-immunant Oct 18, 2023
88e566a
runtime/track_memory_map: consider inability to interpret syscall fatal
fw-immunant Oct 18, 2023
d6089cd
runtime/track_memory_map: manage memory map internally
fw-immunant Nov 1, 2023
5abc742
runtime: avoid deprecated PTRACE_KILL
fw-immunant Nov 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,25 @@ add_executable(track-memory-map
target_link_libraries(track-memory-map PRIVATE memory-map)

add_executable(seccomp-filter
seccomp_filter_demo.c
seccomp_filter.c
)

add_executable(landlock
landlock_demo.c
landlock.c
strv.c
forbid_paths.c
)

add_executable(ia2-sandbox
start.c
seccomp_filter.c
track_memory_map.c
mmap_event.c
get_inferior_pkru.c
landlock.c
strv.c
forbid_paths.c
)
target_link_libraries(ia2-sandbox PRIVATE memory-map)
2 changes: 1 addition & 1 deletion runtime/forbid_paths.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <string.h>

#include "forbid_paths.h"
#include "landlock.h"
#include "landlock_syscall.h"
#include "strv.h"

static int allow_path(const char *path, const int ruleset_fd, bool shallow) {
Expand Down
41 changes: 11 additions & 30 deletions runtime/landlock.c
Original file line number Diff line number Diff line change
@@ -1,28 +1,13 @@
#include "landlock.h"
#include "forbid_paths.h"
#include "strv.h"
#include "landlock_syscall.h"

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(const int argc, char *const argv[], char *const *const envp) {
const char *cmd_path;
char *const *cmd_argv;
int landlock_setup(struct landlock_ctx *ctx) {
int ruleset_fd, abi_ver;
__u64 access_fs_rw = ACCESS_FS_ROUGHLY_READ | ACCESS_FS_ROUGHLY_WRITE;
struct landlock_ruleset_attr ruleset_attr = {
.handled_access_fs = access_fs_rw,
};

if (argc < 2) {
fprintf(stderr, "usage: DENY_PATH=... %s <command>\n\n", basename(argv[0]));
fprintf(stderr, "built against landlock ABI version <= %d\n",
LANDLOCK_ABI_LAST);
return 1;
}
ctx->ruleset_attr.handled_access_fs = ACCESS_FS_ROUGHLY_READ | ACCESS_FS_ROUGHLY_WRITE;

abi_ver = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
if (abi_ver < 0) {
Expand Down Expand Up @@ -67,11 +52,11 @@ int main(const int argc, char *const argv[], char *const *const envp) {
* 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_OR_0;
ctx->ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER_OR_0;
__attribute__((fallthrough));
case 2:
/* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE_OR_0;
ctx->ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE_OR_0;

fprintf(stderr,
"Hint: You should update the running kernel "
Expand All @@ -87,15 +72,16 @@ int main(const int argc, char *const argv[], char *const *const envp) {
"rebuild sandboxer to use features from ABI version %d instead of %d\n",
abi_ver, LANDLOCK_ABI_LAST);
}
access_fs_rw &= ruleset_attr.handled_access_fs;
return 0;
}

ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
int landlock_apply_path_blacklist(const struct landlock_ctx *ctx, const char **paths) {
int ruleset_fd = landlock_create_ruleset(&ctx->ruleset_attr, sizeof(ctx->ruleset_attr), 0);
if (ruleset_fd < 0) {
perror("Failed to create ruleset");
return 1;
}
const char *path = getenv("DENY_PATH");
const char *paths[] = {path, NULL};

if (forbid_paths(paths, ruleset_fd) < 0) {
fprintf(stderr, "Failed to set up path allowlist\n");
return 1;
Expand All @@ -110,12 +96,7 @@ int main(const int argc, char *const argv[], char *const *const envp) {
goto err_close_ruleset;
}
close(ruleset_fd);

cmd_path = argv[1];
cmd_argv = argv + 1;
execvpe(cmd_path, cmd_argv, envp);
perror("execvpe");
return 1;
return 0;

err_close_ruleset:
close(ruleset_fd);
Expand Down
87 changes: 10 additions & 77 deletions runtime/landlock.h
Original file line number Diff line number Diff line change
@@ -1,82 +1,15 @@
#pragma once

#define _GNU_SOURCE
#include <linux/landlock.h>
#include <linux/prctl.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>

static inline int
landlock_create_ruleset(const struct landlock_ruleset_attr *const attr,
const size_t size, const __u32 flags) {
return syscall(__NR_landlock_create_ruleset, attr, size, flags);
}

static inline int landlock_add_rule(const int ruleset_fd,
const enum landlock_rule_type rule_type,
const void *const rule_attr,
const __u32 flags) {
return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, rule_attr,
flags);
}

static inline int landlock_restrict_self(const int ruleset_fd,
const __u32 flags) {
return syscall(__NR_landlock_restrict_self, ruleset_fd, flags);
}

/* clang-format off */

#define ACCESS_FS_WITHIN ( \
LANDLOCK_ACCESS_FS_READ_DIR | \
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)

#define ACCESS_FS_ROUGHLY_READ ( \
LANDLOCK_ACCESS_FS_EXECUTE | \
LANDLOCK_ACCESS_FS_READ_FILE | \
LANDLOCK_ACCESS_FS_READ_DIR)

#ifdef LANDLOCK_ACCESS_FS_REFER
#define LANDLOCK_ACCESS_FS_REFER_OR_0 LANDLOCK_ACCESS_FS_REFER
#else
#define LANDLOCK_ACCESS_FS_REFER_OR_0 0
#endif

#ifdef LANDLOCK_ACCESS_FS_TRUNCATE
#define LANDLOCK_ACCESS_FS_TRUNCATE_OR_0 LANDLOCK_ACCESS_FS_TRUNCATE
#else
#define LANDLOCK_ACCESS_FS_TRUNCATE_OR_0 0
#endif

#define ACCESS_FS_ROUGHLY_WRITE ( \
LANDLOCK_ACCESS_FS_WRITE_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_OR_0 | \
LANDLOCK_ACCESS_FS_TRUNCATE_OR_0)

#define ACCESS_FILE ( \
LANDLOCK_ACCESS_FS_EXECUTE | \
LANDLOCK_ACCESS_FS_WRITE_FILE | \
LANDLOCK_ACCESS_FS_READ_FILE | \
LANDLOCK_ACCESS_FS_TRUNCATE_OR_0)
/* enough context to know how to apply landlock filters to the process */
struct landlock_ctx {
struct landlock_ruleset_attr ruleset_attr;
};

/* clang-format on */
/* set up landlock context. returns nonzero on failure. */
int landlock_setup(struct landlock_ctx *ctx);

#define LANDLOCK_ABI_LAST 3
/* apply landlock context to the process. after this call, landlock cannot be
set up again and PR_SET_NO_NEW_PRIVS has been applied. returns nonzero on
failure. */
int landlock_apply_path_blacklist(const struct landlock_ctx *ctx, const char **paths);
41 changes: 41 additions & 0 deletions runtime/landlock_demo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include "forbid_paths.h"
#include "landlock.h"
#include "landlock_syscall.h"
#include "strv.h"

#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(const int argc, char *const argv[], char *const *const envp) {
const char *cmd_path;
char *const *cmd_argv;

if (argc < 2) {
fprintf(stderr, "usage: DENY_PATH=... %s <command>\n\n", basename(argv[0]));
fprintf(stderr, "built against landlock ABI version <= %d\n",
LANDLOCK_ABI_LAST);
return 1;
}

struct landlock_ctx ctx = {0};
if (landlock_setup(&ctx) != 0) {
return 1;
}

const char *path = getenv("DENY_PATH");
const char *paths[] = {path, NULL};

if (landlock_apply_path_blacklist(&ctx, paths) != 0) {
return 1;
}

cmd_path = argv[1];
cmd_argv = argv + 1;
execvpe(cmd_path, cmd_argv, envp);
perror("execvpe");
return 1;
}
82 changes: 82 additions & 0 deletions runtime/landlock_syscall.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#pragma once

#define _GNU_SOURCE
#include <linux/landlock.h>
#include <linux/prctl.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <unistd.h>

static inline int
landlock_create_ruleset(const struct landlock_ruleset_attr *const attr,
const size_t size, const __u32 flags) {
return syscall(__NR_landlock_create_ruleset, attr, size, flags);
}

static inline int landlock_add_rule(const int ruleset_fd,
const enum landlock_rule_type rule_type,
const void *const rule_attr,
const __u32 flags) {
return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, rule_attr,
flags);
}

static inline int landlock_restrict_self(const int ruleset_fd,
const __u32 flags) {
return syscall(__NR_landlock_restrict_self, ruleset_fd, flags);
}

/* clang-format off */

#define ACCESS_FS_WITHIN ( \
LANDLOCK_ACCESS_FS_READ_DIR | \
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)

#define ACCESS_FS_ROUGHLY_READ ( \
LANDLOCK_ACCESS_FS_EXECUTE | \
LANDLOCK_ACCESS_FS_READ_FILE | \
LANDLOCK_ACCESS_FS_READ_DIR)

#ifdef LANDLOCK_ACCESS_FS_REFER
#define LANDLOCK_ACCESS_FS_REFER_OR_0 LANDLOCK_ACCESS_FS_REFER
#else
#define LANDLOCK_ACCESS_FS_REFER_OR_0 0
#endif

#ifdef LANDLOCK_ACCESS_FS_TRUNCATE
#define LANDLOCK_ACCESS_FS_TRUNCATE_OR_0 LANDLOCK_ACCESS_FS_TRUNCATE
#else
#define LANDLOCK_ACCESS_FS_TRUNCATE_OR_0 0
#endif

#define ACCESS_FS_ROUGHLY_WRITE ( \
LANDLOCK_ACCESS_FS_WRITE_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_OR_0 | \
LANDLOCK_ACCESS_FS_TRUNCATE_OR_0)

#define ACCESS_FILE ( \
LANDLOCK_ACCESS_FS_EXECUTE | \
LANDLOCK_ACCESS_FS_WRITE_FILE | \
LANDLOCK_ACCESS_FS_READ_FILE | \
LANDLOCK_ACCESS_FS_TRUNCATE_OR_0)

/* clang-format on */

#define LANDLOCK_ABI_LAST 3
Loading