diff options
author | smitsohu <smitsohu@gmail.com> | 2022-03-01 01:39:27 +0100 |
---|---|---|
committer | smitsohu <smitsohu@gmail.com> | 2022-03-01 01:39:27 +0100 |
commit | cc23a01bd5514c68f89632d7fb01238d496625a0 (patch) | |
tree | 3f778a203adf43d18d1697077eaf1c0dd1e1c421 | |
parent | whitelist: minor restructuring (diff) | |
download | firejail-cc23a01bd5514c68f89632d7fb01238d496625a0.tar.gz firejail-cc23a01bd5514c68f89632d7fb01238d496625a0.tar.zst firejail-cc23a01bd5514c68f89632d7fb01238d496625a0.zip |
whitelist: avoid nested whitelist mounts
Check mountids while creating path of a new mount target.
If the mountid differs from the top level directory (tmpfs)
mountid, this proves an earlier whitelist command.
It is important to note though that this check is not exhaustive,
as besides nested whitelist commands there are also nested
top level directories. So a user could run:
firejail --whitelist=/a/b --whitelist=/a/b/c where both
a and b are (whitelist) top level directories. Such a command
may result in b and c sharing the filesystem and hence mountid.
In this case the nested nature of the whitelist commands
will go unnoticed.
A more rigorous version will probably need to apply some
sorting to the whitelist command, possibly by means of
glob(3).
-rw-r--r-- | src/firejail/fs_whitelist.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c index 0b860c0d5..3377b2592 100644 --- a/src/firejail/fs_whitelist.c +++ b/src/firejail/fs_whitelist.c | |||
@@ -55,6 +55,13 @@ static int whitelist_mkpath(const char *parentdir, const char *relpath, mode_t m | |||
55 | if (parentfd < 0) | 55 | if (parentfd < 0) |
56 | errExit("open"); | 56 | errExit("open"); |
57 | 57 | ||
58 | // top level directory mount id | ||
59 | int mountid = get_mount_id(parentfd); | ||
60 | if (mountid < 0) { | ||
61 | close(parentfd); | ||
62 | return -1; | ||
63 | } | ||
64 | |||
58 | // work on a copy of the path | 65 | // work on a copy of the path |
59 | char *dup = strdup(relpath); | 66 | char *dup = strdup(relpath); |
60 | if (!dup) | 67 | if (!dup) |
@@ -95,6 +102,15 @@ static int whitelist_mkpath(const char *parentdir, const char *relpath, mode_t m | |||
95 | free(dup); | 102 | free(dup); |
96 | return -1; | 103 | return -1; |
97 | } | 104 | } |
105 | // different mount id indicates earlier whitelist mount | ||
106 | if (get_mount_id(fd) != mountid) { | ||
107 | if (arg_debug || arg_debug_whitelists) | ||
108 | printf("Debug %d: whitelisted already\n", __LINE__); | ||
109 | close(parentfd); | ||
110 | close(fd); | ||
111 | free(dup); | ||
112 | return -1; | ||
113 | } | ||
98 | // move on to next path segment | 114 | // move on to next path segment |
99 | close(parentfd); | 115 | close(parentfd); |
100 | parentfd = fd; | 116 | parentfd = fd; |