From 05ce614aad1e78a0128c06398a2a3f6e9acf55cb Mon Sep 17 00:00:00 2001 From: "Kelvin M. Klann" Date: Mon, 6 Nov 2023 04:29:02 -0300 Subject: [PATCH] landlock: detect support at runtime And ignore landlock-related commands if Landlock is unsupported at runtime. --- src/firejail/firejail.h | 1 + src/firejail/landlock.c | 45 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index f9f4cb4734f..5a96fcbfd02 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -968,6 +968,7 @@ void oom_set(const char *oom_string); // landlock.c #ifdef HAVE_LANDLOCK int ll_get_fd(void); +int ll_is_supported(void); int ll_read(const char *allowed_path); int ll_write(const char *allowed_path); int ll_special(const char *allowed_path); diff --git a/src/firejail/landlock.c b/src/firejail/landlock.c index 69d035646f3..79feac5f0ce 100644 --- a/src/firejail/landlock.c +++ b/src/firejail/landlock.c @@ -28,6 +28,7 @@ #include static int ll_ruleset_fd = -1; +static int ll_abi = -1; int ll_get_fd(void) { return ll_ruleset_fd; @@ -59,7 +60,30 @@ landlock_restrict_self(const int ruleset_fd, const __u32 flags) { } #endif +int ll_is_supported(void) { + if (ll_abi != -1) + goto out; + + int ll_abi = landlock_create_ruleset(NULL, 0, + LANDLOCK_CREATE_RULESET_VERSION); + if (ll_abi < 1) { + ll_abi = 0; + fprintf(stderr, "Warning: Landlock is disabled or not supported: %s, " + "ignoring landlock commands\n", + strerror(errno)); + goto out; + } + if (arg_debug) { + printf("Detected Landlock ABI version %d\n", ll_abi); + } +out: + return ll_abi; +} + static int ll_create_full_ruleset() { + if (!ll_is_supported()) + return -1; + int error; struct landlock_ruleset_attr attr; attr.handled_access_fs = @@ -86,6 +110,9 @@ static int ll_create_full_ruleset() { } int ll_read(const char *allowed_path) { + if (!ll_is_supported()) + return 0; + if (ll_ruleset_fd == -1) ll_ruleset_fd = ll_create_full_ruleset(); @@ -115,6 +142,9 @@ int ll_read(const char *allowed_path) { } int ll_write(const char *allowed_path) { + if (!ll_is_supported()) + return 0; + if (ll_ruleset_fd == -1) ll_ruleset_fd = ll_create_full_ruleset(); @@ -148,6 +178,9 @@ int ll_write(const char *allowed_path) { } int ll_special(const char *allowed_path) { + if (!ll_is_supported()) + return 0; + if (ll_ruleset_fd == -1) ll_ruleset_fd = ll_create_full_ruleset(); @@ -179,6 +212,9 @@ int ll_special(const char *allowed_path) { } int ll_exec(const char *allowed_path) { + if (!ll_is_supported()) + return 0; + if (ll_ruleset_fd == -1) ll_ruleset_fd = ll_create_full_ruleset(); @@ -209,6 +245,9 @@ int ll_exec(const char *allowed_path) { int ll_basic_system(void) { assert(cfg.homedir); + if (!ll_is_supported()) + return 0; + if (ll_ruleset_fd == -1) ll_ruleset_fd = ll_create_full_ruleset(); @@ -256,6 +295,9 @@ int ll_basic_system(void) { } int ll_restrict(__u32 flags) { + if (!ll_is_supported()) + return 0; + int (*fnc[])(const char *) = { ll_read, ll_write, @@ -298,6 +340,9 @@ void ll_add_profile(int type, const char *data) { assert(type < LL_MAX); assert(data); + if (!ll_is_supported()) + return; + const char *str = data; while (*str == ' ' || *str == '\t') str++;