[GH-ISSUE #5505] Empty mkdir's should be cleaned up #3020

Open
opened 2026-05-05 09:40:21 -06:00 by gitea-mirror · 5 comments
Owner

Originally created by @hirak99 on GitHub (Dec 4, 2022).
Original GitHub issue: https://github.com/netblue30/firejail/issues/5505

Description

Firejail has a directive to create empty directories for whitelisting, so that if the sandboxed program creates files in those directory then they are maintained.

These empty directories, created by firejail, are left even if the sandboxed program actually would not create them. This causes a lot of empty directories to be created; e.g. the steam profile makes it for every possible game that may be in the default firejail profile whether you own the game or not.

Steps to Reproduce

Steps to reproduce the behavior

  1. Run steam with the default config for it in firejail, e.g. firejail steam
  2. Exit steam
  3. You'll see a number of directories created on your home directory for games you don't have. For example, .config/RogueLegacy, .klei, .killingfloor to name a few. For a full list, see /etc/firejail/steam.profile

Expected behavior

Firejail should mimic the behavior of the sandboxed application running without it; i.e. not leave a directory if it wasn't actually used by the sandboxed program.

Firejail should check if a directory it made was not used (i.e. is empty), and if so, clean it up. This errs on the side of deleting empty dirs created by the sandboxed program, but arguably that's better than leaving many empty directories silently that the user may not have ever intended for.

Actual behavior

Firejail created a bunch of directories when I sandboxed steam.

Behavior without a profile

The bug is about mkdir directive, and as long as it is used - with or without a profile, it would behave the same.

However, the issue of leaving random directories that the user may be unaware is a problem of the firejail-profile system (not any specific profile).

Additional context

Any other detail that may help to understand/debug the problem

Environment

  • Linux distribution and version: "Arch Linux"
  • Firejail version: 0.9.70 (AUR)

Checklist

  • The issues is caused by firejail (i.e. running the program by path (e.g. /usr/bin/vlc) "fixes" it).
  • I can reproduce the issue without custom modifications (e.g. globals.local).
  • The program has a profile. (If not, request one in https://github.com/netblue30/firejail/issues/1139)
  • The profile (and redirect profile if exists) hasn't already been fixed upstream.
  • I have performed a short search for similar issues (to avoid opening a duplicate).
    • I'm aware of browser-allow-drm yes/browser-disable-u2f no in firejail.config to allow DRM/U2F in browsers.
  • I used --profile=PROFILENAME to set the right profile. (Only relevant for AppImages)
Originally created by @hirak99 on GitHub (Dec 4, 2022). Original GitHub issue: https://github.com/netblue30/firejail/issues/5505 <!-- See the following links for help with formatting: https://guides.github.com/features/mastering-markdown/ https://docs.github.com/en/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax --> ### Description Firejail has a directive to create empty directories for whitelisting, so that if the sandboxed program creates files in those directory then they are maintained. These empty directories, created by firejail, are left even if the sandboxed program actually would not create them. This causes a lot of empty directories to be created; e.g. the steam profile makes it for every possible game that may be in the default firejail profile whether you own the game or not. ### Steps to Reproduce _Steps to reproduce the behavior_ 1. Run steam with the default config for it in firejail, e.g. `firejail steam` 2. Exit steam 3. You'll see a number of directories created on your home directory for games you don't have. For example, `.config/RogueLegacy`, `.klei`, `.killingfloor` to name a few. For a full list, see `/etc/firejail/steam.profile` ### Expected behavior Firejail should mimic the behavior of the sandboxed application running without it; i.e. not leave a directory if it wasn't actually used by the sandboxed program. Firejail should check if a directory it made was not used (i.e. is empty), and if so, clean it up. This errs on the side of deleting empty dirs created by the sandboxed program, but arguably that's better than leaving many empty directories silently that the user may not have ever intended for. ### Actual behavior Firejail created a bunch of directories when I sandboxed steam. ### Behavior without a profile The bug is about `mkdir` directive, and as long as it is used - with or without a profile, it would behave the same. However, the issue of leaving random directories that the user may be unaware is a problem of the firejail-profile system (not any specific profile). ### Additional context _Any other detail that may help to understand/debug the problem_ ### Environment - Linux distribution and version: "Arch Linux" - Firejail version: 0.9.70 (AUR) ### Checklist <!-- Note: Items are checked with an "x", like so: - [x] This is a checked item. --> - [x] The issues is caused by firejail (i.e. running the program by path (e.g. `/usr/bin/vlc`) "fixes" it). - [x] I can reproduce the issue without custom modifications (e.g. globals.local). - [ ] The program has a profile. (If not, request one in `https://github.com/netblue30/firejail/issues/1139`) - [ ] The profile (and redirect profile if exists) hasn't already been fixed [upstream](https://github.com/netblue30/firejail/tree/master/etc). - [x] I have performed a short search for similar issues (to avoid opening a duplicate). - [x] I'm aware of `browser-allow-drm yes`/`browser-disable-u2f no` in `firejail.config` to allow DRM/U2F in browsers. - [ ] I used `--profile=PROFILENAME` to set the right profile. (Only relevant for AppImages)
gitea-mirror added the
enhancement
label 2026-05-05 09:40:21 -06:00
Author
Owner

@ghost commented on GitHub (Dec 4, 2022):

Personally I can sympathise with your views on mkdir (and mkfile for that matter). I try my best to keep a reasonably clean filesystem and it sure isn't nice to have empty dirs/files being created when using Firejail.

That being said, using ignore mkdir and ignore mkfile in either a steam.local override or even in globals.local achieves what you want without touching the code. Whether or not this should be the default Firejail behaviour is something to consider. But I haven't taken the time yet to check how much work it would take to implement such a change.

<!-- gh-comment-id:1336486265 --> @ghost commented on GitHub (Dec 4, 2022): Personally I can sympathise with your views on `mkdir` (and `mkfile` for that matter). I try my best to keep a reasonably clean filesystem and it sure isn't nice to have empty dirs/files being created when using Firejail. That being said, using `ignore mkdir` and `ignore mkfile` in either a `steam.local` override or even in `globals.local` achieves what you want without touching the code. Whether or not this should be the `default` Firejail behaviour is something to consider. But I haven't taken the time yet to check how much work it would take to implement such a change.
Author
Owner

@hirak99 commented on GitHub (Dec 4, 2022):

That being said, using ignore mkdir and ignore mkfile in either a steam.local override or even in globals.local achieves what you want without touching the code.

Yeah, that's a good workaround. But I wouldn't know when new directories are added to a profile after I update firejail, and can still end up with clutter over time.

I know it's not an easy decision (given that even removing the empty directories without checking if they were created by the app isn't exactly ideal).
[That said I kinda prefer to have them deleted if empty. To me it seems like an improvement over the current behavior creating and leaving them, but there are other complexities to consider.]

Thanks for considering this request. Looks like this doesn't have a high priority - I am not blocked since I'm gonna be selective on usage, and no one else appears to have asked for this. I'll leave it to you if you wanna close or deprioritize it.

<!-- gh-comment-id:1336511282 --> @hirak99 commented on GitHub (Dec 4, 2022): > That being said, using ignore mkdir and ignore mkfile in either a steam.local override or even in globals.local achieves what you want without touching the code. Yeah, that's a good workaround. But I wouldn't know when new directories are added to a profile after I update firejail, and can still end up with clutter over time. I know it's not an easy decision (given that even removing the empty directories without checking if they were created by the app isn't exactly ideal). [That said I kinda prefer to have them deleted if empty. To me it seems like an improvement over the current behavior creating and leaving them, but there are other complexities to consider.] Thanks for considering this request. Looks like this doesn't have a high priority - I am not blocked since I'm gonna be selective on usage, and no one else appears to have asked for this. I'll leave it to you if you wanna close or deprioritize it.
Author
Owner

@kmk3 commented on GitHub (Dec 5, 2022):

@hirak99 commented on Dec 4:

I know it's not an easy decision (given that even removing the empty
directories without checking if they were created by the app isn't exactly
ideal). [That said I kinda prefer to have them deleted if empty. To me it
seems like an improvement over the current behavior creating and leaving
them, but there are other complexities to consider.]

Indeed, not sure if defaulting to removing all directories, including those
created by the program would be desirable.

Maybe there could be a remove-empty-mkdirs option that only considers
directories in the given mkdir commands. With a separate command, the user
would have to explicitly opt-in to deleting the empty directories (which seems
to me like less surprising behavior).

This could then be added to globals.local to apply this behavior to every
profile.

<!-- gh-comment-id:1336979277 --> @kmk3 commented on GitHub (Dec 5, 2022): @hirak99 commented [on Dec 4](https://github.com/netblue30/firejail/issues/5505#issuecomment-1336511282): > I know it's not an easy decision (given that even removing the empty > directories without checking if they were created by the app isn't exactly > ideal). [That said I kinda prefer to have them deleted if empty. To me it > seems like an improvement over the current behavior creating and leaving > them, but there are other complexities to consider.] Indeed, not sure if defaulting to removing all directories, including those created by the program would be desirable. Maybe there could be a `remove-empty-mkdirs` option that only considers directories in the given `mkdir` commands. With a separate command, the user would have to explicitly opt-in to deleting the empty directories (which seems to me like less surprising behavior). This could then be added to globals.local to apply this behavior to every profile.
Author
Owner

@kmk3 commented on GitHub (Dec 5, 2022):

For now, here are some workarounds:

Delete every empty directory in the home directory:

find ~/ -type d -print0 | sort -rz | xargs -0 rmdir 2>/dev/null

Search and delete only in the most common locations:

clean-empty-dirs:

#!/bin/sh
# Clean up empty directories created by firejail in the home directory
# See https://github.com/netblue30/firejail/issues/5505

set -eu

# Common mkdir base paths
dirs='
~/.cache
~/.config
~/.local/share
~/.local/state
'

# Delete only dot directories in the root
find ~ -mindepth 1 -maxdepth 1 -type d -name '.*' -print0 | sort -rz |
  xargs -0 rmdir 2>/dev/null

# Delete every empty directory in the other paths
for dir in $dirs; do
	test -z "$dir" && continue
	find "$dir" -mindepth 1 -maxdepth 1 -type d -print0 | sort -rz |
	  xargs -0 rmdir 2>/dev/null
done

For the worst offenders, there could be a $PATH-based override to run the
script after the given program. Example:

~/bin/steam:

#!/bin/sh

firejail /usr/bin/steam
clean-empty-dirs
<!-- gh-comment-id:1337005338 --> @kmk3 commented on GitHub (Dec 5, 2022): For now, here are some workarounds: Delete every empty directory in the home directory: ```sh find ~/ -type d -print0 | sort -rz | xargs -0 rmdir 2>/dev/null ``` Search and delete only in the most common locations: clean-empty-dirs: ```sh #!/bin/sh # Clean up empty directories created by firejail in the home directory # See https://github.com/netblue30/firejail/issues/5505 set -eu # Common mkdir base paths dirs=' ~/.cache ~/.config ~/.local/share ~/.local/state ' # Delete only dot directories in the root find ~ -mindepth 1 -maxdepth 1 -type d -name '.*' -print0 | sort -rz | xargs -0 rmdir 2>/dev/null # Delete every empty directory in the other paths for dir in $dirs; do test -z "$dir" && continue find "$dir" -mindepth 1 -maxdepth 1 -type d -print0 | sort -rz | xargs -0 rmdir 2>/dev/null done ``` For the worst offenders, there could be a `$PATH`-based override to run the script after the given program. Example: ~/bin/steam: ```sh #!/bin/sh firejail /usr/bin/steam clean-empty-dirs ```
Author
Owner

@kmk3 commented on GitHub (Dec 5, 2022):

Long-term this seems like something that could maybe be better served by
supporting post-exec hooks on firejail.

That is, given an entry like post-hook ${HOME}/bar.sh in foo.profile,
register bar.sh as an exit trap before running foo or something (not sure if it
would work this way).

<!-- gh-comment-id:1337009464 --> @kmk3 commented on GitHub (Dec 5, 2022): Long-term this seems like something that could maybe be better served by supporting post-exec hooks on firejail. That is, given an entry like `post-hook ${HOME}/bar.sh` in foo.profile, register bar.sh as an exit trap before running foo or something (not sure if it would work this way).
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#3020
No description provided.