[GH-ISSUE #5] Whitelist /media directory #6

Closed
opened 2026-05-05 04:42:42 -06:00 by gitea-mirror · 19 comments
Owner

Originally created by @boltronics on GitHub (Aug 9, 2015).
Original GitHub issue: https://github.com/netblue30/firejail/issues/5

Currently, it is possible to create a filesystem blacklist:

blacklist /etc/shadow*

However, we cannot create a whitelist in the same way. It would be useful to support both blacklist and whitelist options in the same profile.

Use case:
Often it's easier (and safer, in the event of filesystem changes) to just specify one or two files in a directory you want to grant access to. eg.

blacklist /etc
whitelist /etc/fstab
whitelist /etc/hostname
whitelist /etc/issue
whitelist /etc/localtime
whitelist /etc/mailcap
whitelist /etc/nsswitch.conf
whitelist /etc/passwd
whitelist /etc/resolv.conf
Originally created by @boltronics on GitHub (Aug 9, 2015). Original GitHub issue: https://github.com/netblue30/firejail/issues/5 Currently, it is possible to create a filesystem blacklist: ``` blacklist /etc/shadow* ``` However, we cannot create a whitelist in the same way. It would be useful to support both blacklist and whitelist options in the same profile. Use case: Often it's easier (and safer, in the event of filesystem changes) to just specify one or two files in a directory you want to grant access to. eg. ``` blacklist /etc whitelist /etc/fstab whitelist /etc/hostname whitelist /etc/issue whitelist /etc/localtime whitelist /etc/mailcap whitelist /etc/nsswitch.conf whitelist /etc/passwd whitelist /etc/resolv.conf ```
gitea-mirror 2026-05-05 04:42:42 -06:00
Author
Owner

@netblue30 commented on GitHub (Aug 10, 2015):

This is by far the most requested feature. The problem is once "blacklist /etc" is executed, the directory disappears and "whiltelist /etc/fstab" will not find /etc/fstab.

I did something similar to whitelist for home directory in --private.keep option. The man description is as follows:

   --private.keep=file,directory
          Build a new user home in a temporary filesystem,  and  copy  the
          files and directories in the list in the new home. All modifica‐
          tions are discarded when the sandbox is closed.

          Example:
          $ firejail --private.keep=.mozilla firefox

I'll do the same for /etc directory in a new option --etc.keep. In the profile file it will look like:

         etc.keep fstab,hostname,issue,localtime,mailcap,nsswitch.conf,passwd,resolv.conf
<!-- gh-comment-id:129410469 --> @netblue30 commented on GitHub (Aug 10, 2015): This is by far the most requested feature. The problem is once "blacklist /etc" is executed, the directory disappears and "whiltelist /etc/fstab" will not find /etc/fstab. I did something similar to whitelist for home directory in --private.keep option. The man description is as follows: ``` --private.keep=file,directory Build a new user home in a temporary filesystem, and copy the files and directories in the list in the new home. All modifica‐ tions are discarded when the sandbox is closed. Example: $ firejail --private.keep=.mozilla firefox ``` I'll do the same for /etc directory in a new option --etc.keep. In the profile file it will look like: ``` etc.keep fstab,hostname,issue,localtime,mailcap,nsswitch.conf,passwd,resolv.conf ```
Author
Owner

@boltronics commented on GitHub (Aug 10, 2015):

Hmm... I understand. Would it be possible then to not have the modifications discarded?

So for example, if I wanted to run Iceweasel but only grant access to ${HOME}/.mozilla, ${HOME}/Downloads and nothing else. I could use the --private.keep=..., but then it sounds like my bookmarks and downloads would disappear.

I realise this gets a bit messy when we have multiple applications wanting .mozilla access... I'm not sure of a good solution to deal with that. Maybe recursively creating hard links for anything specified by --private.keep would work?

<!-- gh-comment-id:129419519 --> @boltronics commented on GitHub (Aug 10, 2015): Hmm... I understand. Would it be possible then to not have the modifications discarded? So for example, if I wanted to run Iceweasel but only grant access to ${HOME}/.mozilla, ${HOME}/Downloads and nothing else. I could use the --private.keep=..., but then it sounds like my bookmarks and downloads would disappear. I realise this gets a bit messy when we have multiple applications wanting .mozilla access... I'm not sure of a good solution to deal with that. Maybe recursively creating hard links for anything specified by --private.keep would work?
Author
Owner

@ghost commented on GitHub (Aug 12, 2015):

@boltronics For Iceweasel/Firefox I just create a "firefox" directory in $HOME, then start firejail with the "--private=firefox" option. That way the browser has its own private home directory that other apps can see too. Downloads go to ~/firefox/Downloads and can be seen from outside firejail.

<!-- gh-comment-id:130250768 --> @ghost commented on GitHub (Aug 12, 2015): @boltronics For Iceweasel/Firefox I just create a "firefox" directory in $HOME, then start firejail with the "--private=firefox" option. That way the browser has its own private home directory that other apps can see too. Downloads go to ~/firefox/Downloads and can be seen from outside firejail.
Author
Owner

@boltronics commented on GitHub (Aug 12, 2015):

@pmillerchip Thanks for the tip; that actually works pretty well.

The only nitpick I have there is that the private argument/profile option does not create the directory automatically if it does not already exist. That means I can't just update all my firejail profiles with with the private option, commit to git and deploy everywhere - I need to keep track of a set of basically empty directories everywhere as well, or (more likely) create and commit a script to create them where required.

But this approach is certainly an improvement and gets me most of where I want to be - provided the things I want to blacklist are all under ${HOME}.

<!-- gh-comment-id:130259406 --> @boltronics commented on GitHub (Aug 12, 2015): @pmillerchip Thanks for the tip; that actually works pretty well. The only nitpick I have there is that the `private` argument/profile option does not create the directory automatically if it does not already exist. That means I can't just update all my firejail profiles with with the private option, commit to git and deploy everywhere - I need to keep track of a set of basically empty directories everywhere as well, or (more likely) create and commit a script to create them where required. But this approach is certainly an improvement and gets me most of where I want to be - provided the things I want to blacklist are all under ${HOME}.
Author
Owner

@ghost commented on GitHub (Aug 12, 2015):

@boltronics Creating the directory is certainly possible, but I don't want to write that myself and submit a pull request because I'd be wary of introducing security holes. We'd have a SUID binary creating things in the filesystem on behalf of an unprivileged user using a path they supplied, so you'd have to be extremely careful writing that code. Personally I like the way firejail works at the moment, where if any tiny thing is wrong it exits immediately. As it's SUID root it makes me feel more comfortable.

<!-- gh-comment-id:130272569 --> @ghost commented on GitHub (Aug 12, 2015): @boltronics Creating the directory is certainly possible, but I don't want to write that myself and submit a pull request because I'd be wary of introducing security holes. We'd have a SUID binary creating things in the filesystem on behalf of an unprivileged user using a path they supplied, so you'd have to be extremely careful writing that code. Personally I like the way firejail works at the moment, where if any tiny thing is wrong it exits immediately. As it's SUID root it makes me feel more comfortable.
Author
Owner

@boltronics commented on GitHub (Aug 12, 2015):

@pmillerchip That's a really good point.

With that in mind, why do we have firejail set to be SUID directly? If we look at Chromium (for example), /usr/bin/chromium is not SUID, but rather it calls /usr/lib/chromium/chrome-sandbox for just the part of the execution where it's strictly required. For example, I can delete that file, and chromium --version still works as expected.

It seems firejail would probably benefit from a similar setup (and we already have a couple of executable files under /usr/lib/firejail too). I imagine that would alleviate such concerns?

There's probably a fair bit of code running SUID already that isn't strictly necessary, such as (I imagine) the config parser stuff.

<!-- gh-comment-id:130281371 --> @boltronics commented on GitHub (Aug 12, 2015): @pmillerchip That's a really good point. With that in mind, why do we have firejail set to be SUID directly? If we look at Chromium (for example), `/usr/bin/chromium` is not SUID, but rather it calls `/usr/lib/chromium/chrome-sandbox` for just the part of the execution where it's strictly required. For example, I can delete that file, and `chromium --version` still works as expected. It seems firejail would probably benefit from a similar setup (and we already have a couple of executable files under `/usr/lib/firejail` too). I imagine that would alleviate such concerns? There's probably a fair bit of code running SUID already that isn't strictly necessary, such as (I imagine) the config parser stuff.
Author
Owner

@ghost commented on GitHub (Aug 12, 2015):

@boltronics I did some looking, it seems firejail already performs some copying in the "--private.keep" option. It forks a child process which drops all privileges and performs the copy. As there's already code for this, it could be adapted to set up the private home directory in the same way for the "--private=dir" option.

Restructuring firejail with a separate SUID part is a nice idea, but I fear it would be a lot of work for poor netblue30!

<!-- gh-comment-id:130285857 --> @ghost commented on GitHub (Aug 12, 2015): @boltronics I did some looking, it seems firejail already performs some copying in the "--private.keep" option. It forks a child process which drops all privileges and performs the copy. As there's already code for this, it could be adapted to set up the private home directory in the same way for the "--private=dir" option. Restructuring firejail with a separate SUID part is a nice idea, but I fear it would be a lot of work for poor netblue30!
Author
Owner

@netblue30 commented on GitHub (Aug 12, 2015):

pmillerchip is right, I'm asking for trouble creating new directories.

I ended up implementing a --private-etc option as follows:

  --private-etc=file,directory
          Build  a  new /etc in a temporary filesystem, and copy the files
          and directories in the list.  All  modifications  are  discarded
          when the sandbox is closed.

          Example:
          $ firejail --private-etc=group,hostname,localtime, \
          nsswitch.conf,passwd,resolv.conf

(similar for profiles)

<!-- gh-comment-id:130287222 --> @netblue30 commented on GitHub (Aug 12, 2015): pmillerchip is right, I'm asking for trouble creating new directories. I ended up implementing a --private-etc option as follows: ``` --private-etc=file,directory Build a new /etc in a temporary filesystem, and copy the files and directories in the list. All modifications are discarded when the sandbox is closed. Example: $ firejail --private-etc=group,hostname,localtime, \ nsswitch.conf,passwd,resolv.conf ``` (similar for profiles)
Author
Owner

@boltronics commented on GitHub (Aug 12, 2015):

Thanks netblue30!

<!-- gh-comment-id:130288865 --> @boltronics commented on GitHub (Aug 12, 2015): Thanks netblue30!
Author
Owner

@netblue30 commented on GitHub (Aug 12, 2015):

No problem, I'll close the bug for now.

<!-- gh-comment-id:130320459 --> @netblue30 commented on GitHub (Aug 12, 2015): No problem, I'll close the bug for now.
Author
Owner

@ghost commented on GitHub (Oct 26, 2015):

Bringing this issue back up.

I have Steam games stored on another drive. I'd like for Steam to be able to access those, but not to any other folders on that drive.

E.g. something like:

blacklist /media
whitelist /media/*user*/*drive*/Steam

Perhaps there could be a more generic --keep flag?

<!-- gh-comment-id:151228798 --> @ghost commented on GitHub (Oct 26, 2015): Bringing this issue back up. I have Steam games stored on another drive. I'd like for Steam to be able to access those, but not to any other folders on that drive. E.g. something like: ``` blacklist /media whitelist /media/*user*/*drive*/Steam ``` Perhaps there could be a more generic --keep flag?
Author
Owner

@netblue30 commented on GitHub (Oct 26, 2015):

I think I can build some sort of whitelisting for /media.

<!-- gh-comment-id:151252430 --> @netblue30 commented on GitHub (Oct 26, 2015): I think I can build some sort of whitelisting for /media.
Author
Owner

@ghost commented on GitHub (Oct 26, 2015):

Well on Ubuntu it's /media/user/disk. On Fedora it's /var/run/user/disk.

You can see where this starts getting a big complex.

<!-- gh-comment-id:151260102 --> @ghost commented on GitHub (Oct 26, 2015): Well on Ubuntu it's /media/user/disk. On Fedora it's /var/run/user/disk. You can see where this starts getting a big complex.
Author
Owner

@netblue30 commented on GitHub (Oct 27, 2015):

It is all over the place. In Debian wheezy is on /media.

The number of entries in /media is small. Blacklist whatever you don't need for now.

<!-- gh-comment-id:151586752 --> @netblue30 commented on GitHub (Oct 27, 2015): It is all over the place. In Debian wheezy is on /media. The number of entries in /media is small. Blacklist whatever you don't need for now.
Author
Owner

@netblue30 commented on GitHub (Nov 15, 2015):

Implemented!

Whitelist command now accepts user home, /dev, /media, /var, and /tmp directories.

<!-- gh-comment-id:156815916 --> @netblue30 commented on GitHub (Nov 15, 2015): Implemented! Whitelist command now accepts user home, /dev, /media, /var, and /tmp directories.
Author
Owner

@SkewedZeppelin commented on GitHub (Sep 13, 2016):

@netblue30 could you please make whitelist also accept /mnt? or a config option to disable that check? Thanks.

<!-- gh-comment-id:246852204 --> @SkewedZeppelin commented on GitHub (Sep 13, 2016): @netblue30 could you please make whitelist also accept /mnt? or a config option to disable that check? Thanks.
Author
Owner

@netblue30 commented on GitHub (Sep 15, 2016):

I'll add support for it, moved here: https://github.com/netblue30/firejail/issues/781

<!-- gh-comment-id:247347690 --> @netblue30 commented on GitHub (Sep 15, 2016): I'll add support for it, moved here: https://github.com/netblue30/firejail/issues/781
Author
Owner

@g4jc commented on GitHub (Nov 24, 2016):

I've found a possible solution to this problem, but for unknown reasons firejail fights it's own permissions and shuts down.

Examine the following:

/usr/bin/firejail --noprofile --seccomp --netfilter --nonewprivs --noroot --nogroups $(find /home -maxdepth 2 -type f -not -name ".Xauthority" -not -name ".icedove" -not -name ".gnupg" | awk 1 ORS=' --blacklist=' | rev | cut -c 14- | rev ) --caps.drop=all --private-etc=/etc --private-bin=gpg2 --private-tmp /usr/lib/icedove/icedove

What this one-liner does is nest a find command in firejail startup which creates a properly parsed "--blacklist" for everything in everyone's home folder. It also creates a whitelist via find's "not-name" command - Then it runs the program.

The problem with this method is files in your home directory will randomly fail and the script gets stuck.

Parent pid 21911, child pid 21912 Child process initialized /bin/bash: /home/user/readme.[2015-01-20].txt: Permission denied Parent is shutting down, bye...

I am unsure if this is a race condition or if firejail is blocking files prior to running --black-list.

<!-- gh-comment-id:262825823 --> @g4jc commented on GitHub (Nov 24, 2016): I've found a possible solution to this problem, but for unknown reasons firejail fights it's own permissions and shuts down. Examine the following: `/usr/bin/firejail --noprofile --seccomp --netfilter --nonewprivs --noroot --nogroups $(find /home -maxdepth 2 -type f -not -name ".Xauthority" -not -name ".icedove" -not -name ".gnupg" | awk 1 ORS=' --blacklist=' | rev | cut -c 14- | rev ) --caps.drop=all --private-etc=/etc --private-bin=gpg2 --private-tmp /usr/lib/icedove/icedove` What this one-liner does is nest a find command in firejail startup which creates a properly parsed "--blacklist" for everything in everyone's home folder. It also creates a whitelist via find's "not-name" command - Then it runs the program. The problem with this method is files in your home directory will randomly fail and the script gets stuck. `Parent pid 21911, child pid 21912 Child process initialized /bin/bash: /home/user/readme.[2015-01-20].txt: Permission denied Parent is shutting down, bye...` I am unsure if this is a race condition or if firejail is blocking files prior to running --black-list.
Author
Owner

@netblue30 commented on GitHub (Nov 27, 2016):

I'll look into it, thanks.

<!-- gh-comment-id:263124684 --> @netblue30 commented on GitHub (Nov 27, 2016): I'll look into it, thanks.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#6
No description provided.