Skip to content

Commit

Permalink
whitelist: avoid nested whitelist mounts
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
smitsohu committed Mar 1, 2022
1 parent f60dbcd commit cc23a01
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/firejail/fs_whitelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ static int whitelist_mkpath(const char *parentdir, const char *relpath, mode_t m
if (parentfd < 0)
errExit("open");

// top level directory mount id
int mountid = get_mount_id(parentfd);
if (mountid < 0) {
close(parentfd);
return -1;
}

// work on a copy of the path
char *dup = strdup(relpath);
if (!dup)
Expand Down Expand Up @@ -95,6 +102,15 @@ static int whitelist_mkpath(const char *parentdir, const char *relpath, mode_t m
free(dup);
return -1;
}
// different mount id indicates earlier whitelist mount
if (get_mount_id(fd) != mountid) {
if (arg_debug || arg_debug_whitelists)
printf("Debug %d: whitelisted already\n", __LINE__);
close(parentfd);
close(fd);
free(dup);
return -1;
}
// move on to next path segment
close(parentfd);
parentfd = fd;
Expand Down

0 comments on commit cc23a01

Please sign in to comment.