Subject: firejail: Unable to create a whitelisted config file
Date: Thu, 21 Jul 2022 19:53:22 +0200
Package: firejail
Version: 0.9.64.4-2
Severity: normal
X-Debbugs-Cc: [email protected]
The app “toot” generally needs to create and access this config file:
~/.config/toot/config.json
For organizational and backup reasons, I’ve taken these steps
(in effect):
$ mv ~/.config ~/my_config_files
$ ln -s ~/my_config_files ~/.config
So ~/.config is a symlink pointing to ~/my_config_files. To avoid
supplying a symlink to Firejail, it’s launched as follows:
$ firejail --env=XDG_CONFIG_HOME="$HOME"/my_config_files\
--whitelist="$(readlink $HOME/.config)"toot/config.json\
--noblacklist="$(readlink $HOME/.config)"toot/config.json\
toot login
The readlink command substitution converts the symlink to a full
absolute pathname (not symbolic). Passing the XDG_CONFIG_HOME
variable ensures that the app itself makes no reference to the
symbolic link, which is confirmed by the app’s output showing:
===8<------------------------------
Creating config file at /home/user/my_config_files/toot/config.json
===8<------------------------------
The app runs without issue, but when the app terminates there is no
existing file /home/user/my_config_files/toot/config.json.
-- System Information:
Debian Release: 11.4
APT prefers stable-updates
APT policy: (990, 'stable-updates'), (990, 'stable-security'), (990, 'testing'), (990, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 5.10.0-16-amd64 (SMP w/2 CPU threads)
Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages firejail depends on:
ii libapparmor1 2.13.6-10
ii libc6 2.31-13+deb11u3
ii libselinux1 3.1-3
Versions of packages firejail recommends:
ii firejail-profiles 0.9.64.4-2+deb11u1
ii iproute2 5.10.0-4
ii iptables 1.8.7-1
ii xauth 1:1.1-1
ii xdg-dbus-proxy 0.1.2-2
ii xpra 3.0.13+dfsg1-1
ii xvfb 2:1.20.11-1+deb11u1
firejail suggests no packages.
-- Configuration Files:
/etc/firejail/firejail.config changed [not included]
-- no debconf information
Acknowledgement sent
to Reiner Herrmann <[email protected]>:
Extra info received and forwarded to list.
(Thu, 21 Jul 2022 18:54:03 GMT) (full text, mbox, link).
Subject: Re: Bug#1015816: firejail: Unable to create a whitelisted config file
Date: Thu, 21 Jul 2022 20:45:12 +0200
Hi,
On Thu, Jul 21, 2022 at 07:53:22PM +0200, anonymous coward wrote:
> $ firejail --env=XDG_CONFIG_HOME="$HOME"/my_config_files\
> --whitelist="$(readlink $HOME/.config)"toot/config.json\
> --noblacklist="$(readlink $HOME/.config)"toot/config.json\
> toot login
>
> The readlink command substitution converts the symlink to a full
> absolute pathname (not symbolic). Passing the XDG_CONFIG_HOME
> variable ensures that the app itself makes no reference to the
> symbolic link, which is confirmed by the app’s output showing:
>
> ===8<------------------------------
> Creating config file at /home/user/my_config_files/toot/config.json
> ===8<------------------------------
>
> The app runs without issue, but when the app terminates there is no
> existing file /home/user/my_config_files/toot/config.json.
Can you please try specifying the "mkdir" setting, to create the
directory before whitelisting?
(Or alternatively make sure it exists before starting the jail)
See firejail-profiles(5):
> mkdir directory
> Create a directory in user home, under /tmp, or under /run/user/<UID> before the sandbox
> is started. The directory is created if it doesn't already exist.
>
> Use this command for whitelisted directories you need to preserve when the sandbox is
> closed. Without it, the application will create the directory, and the directory will be
> deleted when the sandbox is closed. Subdirectories are recursively created.
Kind regards,
Reiner
Subject: Re: firejail: Unable to create a whitelisted config file
Date: Mon, 25 Jul 2022 10:43:04 +0200
Package: firejail
Version: 0.9.64.4-2
Followup-For: Bug #1015816
X-Debbugs-Cc: [email protected]
It was an interesting suggestion but in the end it made no
difference. And in fact the test inspires a feature request.
I created /tmp/toot.profile as follows:
===8<------------------------------
mkdir ~/my_config_files/toot/
===8<------------------------------
Then I ran the same command as previously, but added
“--profile=/tmp/toot.profile”. It ran just the same as it did
previously, except the only difference is that ~/my_config_files/toot/
persists. So it runs successfully, exits, and leaves the empty
directory ~/my_config_files/toot/. The fact that it’s empty is the
problem. The config file created therein must persist as well.
The output is the same as before apart from also printing the
following line upon launch:
===8<------------------------------
…
Reading profile /tmp/toot.profile
…
===8<------------------------------
It was useful to see an indicator that the profile was read. It’s a
little annoying that firejail does not inform the user that it’s
creating a directory. After reading the profile, it eventually
executes “mkdir ~/my_config_files/toot/” without telling the user. So
as a feature request I suggest printing that action in the output.
Even if the /mkdir/ parameter were to have fixed the problem, it would
have simply been a workaround. That is, it’s not always trivial (or
even possible) to predict which directories an app will
create. Firejail should permit an app to arbitrarily create any
directories on-the-fly as needed-- to the extent that it has write
permission in the applicable directory.
In a 2nd test I took your suggestion a step further, and expanded
/tmp/toot.profile to also create the file:
===8<------------------------------
mkdir ~/my_config_files/toot/
mkfile ~/my_config_files/toot/config.json
===8<------------------------------
Firejail successfully created an empty config file, but this time it
fell over. When I say “it” fell over, I don’t know if Firejail fell
over or if the app did. I’m speculating that the app’s JSON parser did
not like finding any empty file. This was the output:
===8<------------------------------
Traceback (most recent call last):
File "/usr/bin/toot", line 11, in <module>
load_entry_point('toot==0.27.0', 'console_scripts', 'toot')()
File "/usr/lib/python3/dist-packages/toot/console.py", line 547, in main
user, app = config.get_active_user_app()
File "/usr/lib/python3/dist-packages/toot/config.py", line 94, in get_active_user_app
config = load_config()
File "/usr/lib/python3/dist-packages/toot/config.py", line 70, in load_config
return json.load(f)
File "/usr/lib/python3.9/json/__init__.py", line 293, in load
return loads(fp.read(),
File "/usr/lib/python3.9/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.9/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 2 column 1 (char 1)
===8<------------------------------
I think I might have previously reported the difficulty in
distinguising an app error from a firejail error because FJ does not
tag its own output. In any case, to summarize, I’ll enumerate the 3
outstanding issues:
1) The config file for the /toot/ app is apparently created within the
sandbox but it fails to persist when the app terminates (regardless of
whether or not the mkdir parameter is used).
2) The mkdir and mkfile profile parameters take effect (as expected),
but Firejail neglects to inform the user of this.
3) Firejail errors are often indistinguishible from child process
errors because FJ makes no effort to tag its own output.
-- System Information:
Debian Release: 11.4
APT prefers stable-updates
APT policy: (990, 'stable-updates'), (990, 'stable-security'), (990, 'testing'), (990, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 5.10.0-16-amd64 (SMP w/2 CPU threads)
Kernel taint flags: TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled
Versions of packages firejail depends on:
ii libapparmor1 2.13.6-10
ii libc6 2.31-13+deb11u3
ii libselinux1 3.1-3
Versions of packages firejail recommends:
ii firejail-profiles 0.9.64.4-2+deb11u1
ii iproute2 5.10.0-4
ii iptables 1.8.7-1
ii xauth 1:1.1-1
ii xdg-dbus-proxy 0.1.2-2
ii xpra 3.0.13+dfsg1-1
ii xvfb 2:1.20.11-1+deb11u1
firejail suggests no packages.
-- Configuration Files:
/etc/firejail/firejail.config changed [not included]
-- no debconf information
Subject: Re: firejail: Unable to create a whitelisted config file
Date: Mon, 25 Jul 2022 11:47:34 +0200
Package: firejail
Version: 0.9.64.4-2
Followup-For: Bug #1015816
X-Debbugs-Cc: [email protected]
To cover all bases, I also tried enabling the read-write perms,
effectively running:
$ firejail --env=XDG_CONFIG_HOME="$HOME"/my_config_files\
--whitelist="$(readlink $HOME/.config)"toot/config.json\
--noblacklist="$(readlink $HOME/.config)"toot/config.json\
--profile=<(printf '%s\n' 'mkdir ~/tools/conf/toot')\
--read-write="$HOME"/my_config_files/toot\
--read-write="$HOME"/my_config_files/toot/config.json\
toot login
It made no difference. It still just leaves the empty directory
"$HOME"/my_config_files/toot.
As a possible secondary bug in the docs, the man page contains:
===8<------------------------------
--read-write=dirname_or_filename
Set directory or file read-write. Only files or directories belonging to the current user are allowed for this operation.
File globbing is supported, see FILE GLOBBING section for more details. Example:
$ mkdir ~/test
$ touch ~/test/a
$ firejail --read-only=~/test --read-write=~/test/a
===8<------------------------------
The man page does not state what the default perms are. The whitelist
option in the man page says: “Modifications to whitelisted files are
persistent”. This seems to imply that the read-write option is the
default setting on whitelisted dirs, but makes no mention of what
happens if read-write is used on a non-whitelisted dir. The example
given somewhat implies that read-write is useful when giving different
perms to a subdir than the parent dir. But it does not outright state
this so users are left guessing.
I should also say it’s unclear whether the noblacklist option is
useful or redundant. Does --whitelist imply --noblacklist
automatically? The man page should make that clear.
Debbugs is free software and licensed under the terms of the GNU General
Public License version 2. The current version can be obtained
from https://bugs.debian.org/debbugs-source/.