From f70ffbe76cd06c03442132f06d503846a415f24c Mon Sep 17 00:00:00 2001 From: "Kelvin M. Klann" Date: Thu, 1 Feb 2024 23:21:26 -0300 Subject: [PATCH] landlock: split .special into .makeipc and .makedev As discussed with @topimiettinen[1], it is unlikely that an unprivileged process would need to directly create block or character devices. Also, `landlock.special` is not very descriptive of what it allows. So split `landlock.special` into: * `landlock.makeipc`: allow creating named pipes and sockets (which are usually used for inter-process communication) * `landlock.makedev`: allow creating block and character devices Misc: The `makedev` name is based on `nodev` from mount(8), which makes mount not interpret block and character devices. `ipc` was suggested by @rusty-snake[2]. Relates to #6078. [1] https://github.com/netblue30/firejail/pull/6078#pullrequestreview-1740569786 [2] https://github.com/netblue30/firejail/pull/6187#issuecomment-1924107294 --- contrib/syntax/lists/profile_commands_arg1.list | 3 ++- etc/inc/landlock-common.inc | 2 +- etc/templates/profile.template | 3 ++- src/bash_completion/firejail.bash_completion.in | 6 +++++- src/firejail/firejail.h | 7 ++++--- src/firejail/landlock.c | 15 +++++++++++---- src/firejail/main.c | 6 ++++-- src/firejail/profile.c | 8 ++++++-- src/firejail/usage.c | 3 ++- src/man/firejail-profile.5.in | 11 ++++++++--- src/man/firejail.1.in | 11 ++++++++--- src/zsh_completion/_firejail.in | 3 ++- 12 files changed, 55 insertions(+), 23 deletions(-) diff --git a/contrib/syntax/lists/profile_commands_arg1.list b/contrib/syntax/lists/profile_commands_arg1.list index e76b6ef40b9..8d5cae7f2ce 100644 --- a/contrib/syntax/lists/profile_commands_arg1.list +++ b/contrib/syntax/lists/profile_commands_arg1.list @@ -30,8 +30,9 @@ iprange join-or-start keep-fd landlock.execute +landlock.makedev +landlock.makeipc landlock.read -landlock.special landlock.write mac mkdir diff --git a/etc/inc/landlock-common.inc b/etc/inc/landlock-common.inc index ebe9f98dc91..694d447b594 100644 --- a/etc/inc/landlock-common.inc +++ b/etc/inc/landlock-common.inc @@ -4,7 +4,7 @@ include landlock-common.local landlock.read / # whole system read landlock.read /proc -landlock.special / # sockets etc. +landlock.makeipc / # sockets etc. # write access landlock.write ${HOME} diff --git a/etc/templates/profile.template b/etc/templates/profile.template index 8882c9012bb..0e6a5734ec5 100644 --- a/etc/templates/profile.template +++ b/etc/templates/profile.template @@ -140,7 +140,8 @@ include globals.local # Landlock commands ##landlock.read PATH ##landlock.write PATH -##landlock.special PATH +##landlock.makeipc PATH +##landlock.makedev PATH ##landlock.execute PATH #include landlock-common.inc diff --git a/src/bash_completion/firejail.bash_completion.in b/src/bash_completion/firejail.bash_completion.in index 76667ca0cab..6c985bc6ef6 100644 --- a/src/bash_completion/firejail.bash_completion.in +++ b/src/bash_completion/firejail.bash_completion.in @@ -53,7 +53,11 @@ _firejail() _filedir return 0 ;; - --landlock.special) + --landlock.makeipc) + _filedir + return 0 + ;; + --landlock.makedev) _filedir return 0 ;; diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index eb9287f2ef9..2122649cf2f 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -154,9 +154,10 @@ typedef struct landlock_entry_t { struct landlock_entry_t *next; #define LL_READ 0 #define LL_WRITE 1 -#define LL_SPECIAL 2 -#define LL_EXEC 3 -#define LL_MAX 4 +#define LL_MAKEIPC 2 +#define LL_MAKEDEV 3 +#define LL_EXEC 4 +#define LL_MAX 5 int type; char *data; } LandlockEntry; diff --git a/src/firejail/landlock.c b/src/firejail/landlock.c index 77149a13426..c445e74d9fe 100644 --- a/src/firejail/landlock.c +++ b/src/firejail/landlock.c @@ -194,16 +194,22 @@ static void ll_write(const char *allowed_path) { ll_fs(allowed_path, allowed_access, __func__); } -static void ll_special(const char *allowed_path) { +static void ll_makeipc(const char *allowed_path) { __u64 allowed_access = - LANDLOCK_ACCESS_FS_MAKE_BLOCK | - LANDLOCK_ACCESS_FS_MAKE_CHAR | LANDLOCK_ACCESS_FS_MAKE_FIFO | LANDLOCK_ACCESS_FS_MAKE_SOCK; ll_fs(allowed_path, allowed_access, __func__); } +static void ll_makedev(const char *allowed_path) { + __u64 allowed_access = + LANDLOCK_ACCESS_FS_MAKE_BLOCK | + LANDLOCK_ACCESS_FS_MAKE_CHAR; + + ll_fs(allowed_path, allowed_access, __func__); +} + static void ll_exec(const char *allowed_path) { __u64 allowed_access = LANDLOCK_ACCESS_FS_EXECUTE; @@ -223,7 +229,8 @@ int ll_restrict(uint32_t flags) { void (*fnc[])(const char *) = { ll_read, ll_write, - ll_special, + ll_makeipc, + ll_makedev, ll_exec, NULL }; diff --git a/src/firejail/main.c b/src/firejail/main.c index 341bac058b0..4d8ea20c3c5 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -1509,8 +1509,10 @@ int main(int argc, char **argv, char **envp) { ll_add_profile(LL_READ, argv[i] + 16); else if (strncmp(argv[i], "--landlock.write=", 17) == 0) ll_add_profile(LL_WRITE, argv[i] + 17); - else if (strncmp(argv[i], "--landlock.special=", 19) == 0) - ll_add_profile(LL_SPECIAL, argv[i] + 19); + else if (strncmp(argv[i], "--landlock.makeipc=", 19) == 0) + ll_add_profile(LL_MAKEIPC, argv[i] + 19); + else if (strncmp(argv[i], "--landlock.makedev=", 19) == 0) + ll_add_profile(LL_MAKEDEV, argv[i] + 19); else if (strncmp(argv[i], "--landlock.execute=", 19) == 0) ll_add_profile(LL_EXEC, argv[i] + 19); #endif diff --git a/src/firejail/profile.c b/src/firejail/profile.c index c0abc339815..a5a8393e972 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -1086,8 +1086,12 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { ll_add_profile(LL_WRITE, ptr + 15); return 0; } - if (strncmp(ptr, "landlock.special ", 17) == 0) { - ll_add_profile(LL_SPECIAL, ptr + 17); + if (strncmp(ptr, "landlock.makeipc ", 17) == 0) { + ll_add_profile(LL_MAKEIPC, ptr + 17); + return 0; + } + if (strncmp(ptr, "landlock.makedev ", 17) == 0) { + ll_add_profile(LL_MAKEDEV, ptr + 17); return 0; } if (strncmp(ptr, "landlock.execute ", 17) == 0) { diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 8598abd9d24..c62e8c3691d 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c @@ -137,7 +137,8 @@ static const char *const usage_str = " --landlock.enforce - enforce the Landlock ruleset.\n" " --landlock.read=path - add a read access rule for the path to the Landlock ruleset.\n" " --landlock.write=path - add a write access rule for the path to the Landlock ruleset.\n" - " --landlock.special=path - add an access rule for the path to the Landlock ruleset for creating block/char devices, named pipes and sockets.\n" + " --landlock.makeipc=path - add an access rule for the path to the Landlock ruleset for creating named pipes and sockets.\n" + " --landlock.makedev=path - add an access rule for the path to the Landlock ruleset for creating block/char devices.\n" " --landlock.execute=path - add an execute access rule for the path to the Landlock ruleset.\n" #endif " --list - list all sandboxes.\n" diff --git a/src/man/firejail-profile.5.in b/src/man/firejail-profile.5.in index e1d7fde9432..b6672c16b84 100644 --- a/src/man/firejail-profile.5.in +++ b/src/man/firejail-profile.5.in @@ -522,10 +522,15 @@ rule for path. Create a Landlock ruleset (if it doesn't already exist) and add a write access rule for path. .TP -\fBlandlock.special path +\fBlandlock.makeipc path Create a Landlock ruleset (if it doesn't already exist) and add a rule that -allows the creation of block devices, character devices, named pipes (FIFOs) -and Unix domain sockets beneath given path. +allows the creation of named pipes (FIFOs) and Unix domain sockets beneath +the given path. +.TP +\fBlandlock.makedev path +Create a Landlock ruleset (if it doesn't already exist) and add a rule that +allows the creation of block devices and character devices beneath the given +path. .TP \fBlandlock.execute path Create a Landlock ruleset (if it doesn't already exist) and add an execution diff --git a/src/man/firejail.1.in b/src/man/firejail.1.in index ccc9a50a561..ed1b0bd4aa6 100644 --- a/src/man/firejail.1.in +++ b/src/man/firejail.1.in @@ -1249,10 +1249,15 @@ rule for path. Create a Landlock ruleset (if it doesn't already exist) and add a write access rule for path. .TP -\fB\-\-landlock.special=path +\fB\-\-landlock.makeipc=path Create a Landlock ruleset (if it doesn't already exist) and add a rule that -allows the creation of block devices, character devices, named pipes (FIFOs) -and Unix domain sockets beneath given path. +allows the creation of named pipes (FIFOs) and Unix domain sockets beneath +the given path. +.TP +\fB\-\-landlock.makedev=path +Create a Landlock ruleset (if it doesn't already exist) and add a rule that +allows the creation of block devices and character devices beneath the given +path. .TP \fB\-\-landlock.execute=path Create a Landlock ruleset (if it doesn't already exist) and add an execution diff --git a/src/zsh_completion/_firejail.in b/src/zsh_completion/_firejail.in index c4056b902e9..45f24d5f3b4 100644 --- a/src/zsh_completion/_firejail.in +++ b/src/zsh_completion/_firejail.in @@ -110,7 +110,8 @@ _firejail_args=( '--landlock.enforce[enforce the Landlock ruleset]' '--landlock.read=-[add a read access rule for the path to the Landlock ruleset]: :_files' '--landlock.write=-[add a write access rule for the path to the Landlock ruleset]: :_files' - '--landlock.special=-[add an access rule for the path to the Landlock ruleset for creating block/char devices, named pipes and sockets]: :_files' + '--landlock.makeipc=-[add an access rule for the path to the Landlock ruleset for creating named pipes and sockets]: :_files' + '--landlock.makedev=-[add an access rule for the path to the Landlock ruleset for creating block/char devices]: :_files' '--landlock.execute=-[add an execute access rule for the path to the Landlock ruleset]: :_files' #endif '--machine-id[spoof /etc/machine-id with a random id]'