Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot start firejailed app from a path on a gocryptfs filesystem #3798

Open
oliversturm opened this issue Dec 8, 2020 · 23 comments
Open

Cannot start firejailed app from a path on a gocryptfs filesystem #3798

oliversturm opened this issue Dec 8, 2020 · 23 comments
Labels
bug Something isn't working
Milestone

Comments

@oliversturm
Copy link

This problem may be related to #3199, but it's different.

Firejail has trouble accessing a (non-existent!) xxx.local profile file when I run it from a folder that is mounted using gocryptfs.

This works:

➜ pwd
/home/sturm
➜ firejail /usr/bin/qpdfview /home/sturm/test.pdf

But this does not work - /home/sturm/cryptmount is an encrypted folder.

➜ mount
...
/home/sturm/cryptdata on /home/sturm/cryptmount type fuse.gocryptfs (rw,nosuid,nodev,relatime,user_id=1000,group_id=1000,max_read=131072)

➜ cd ~/cryptmount

➜ firejail /usr/bin/qpdfview /home/sturm/test.pdf
Reading profile /etc/firejail/qpdfview.profile
Error: cannot access profile file: qpdfview.local

Note that qpdfview.local does not exist anywhere. Also, qpdfview is a random choice - any other tool that has a profile in /etc/firejail and includes a xxx.local file shows the same behavior. For reference, /etc/firejail/qpdfview.profile (unchanged by me) includes this line near the top:

include qpdfview.local

Bug and expected behavior - What did you expect to happen?

I expect to be able to run firejail from any path (including gocryptfs mounts) and see consistent outcome (and preferably no errors).

Environment

  • Arch Linux, Firejail 0.9.64, gocryptfs 1.8.0
@SkewedZeppelin
Copy link
Collaborator

SkewedZeppelin commented Dec 8, 2020 via email

@oliversturm
Copy link
Author

I was using zsh, but I just tried the same thing in bash and the behavior remains the same.

@oliversturm
Copy link
Author

So... it looks to me as if firejail is doing something that uses the current working directory, while it attempts to load qpdfview.local via the include instruction. And whatever that is, it fails when CWD is on a gocryptfs mount. I was almost expecting that somebody with good knowledge of the code would have an idea quickly - but apparently no such luck :)

@rusty-snake
Copy link
Collaborator

firejail will fail on fuse mounts w/o allow_root or allow_other. Does it work with one of them?

@oliversturm
Copy link
Author

Hm... haven't tested this yet. I saw something about this previously, but I obviously assumed that it would apply only if any of the data relevant to firejail was actually stored on that mount. In my case, it's only the current working directory that is on the mount, but there is no reason for firejail to look at this working directory. And in fact it all works fine - if I use --noprofile or comment the include line in the profile. So are you sure there is a reason here that the mount parameters should be at fault?

@oliversturm
Copy link
Author

For instance, this works perfectly fine for me. I'm accessing a file that is on the mount, but the current working directory is not on the mount.

➜ pwd
/home/sturm

➜ firejail /usr/bin/qpdfview /home/sturm/cryptmount/test.pdf

@rusty-snake
Copy link
Collaborator

rusty-snake commented Dec 8, 2020

Somehow read the mount output above like $HOME was the mount. Anyway, the relevant is

if (access(fname, R_OK)) {
int errsv = errno;
// if the file ends in ".local", do not exit
const char *base = gnu_basename(fname);
char *ptr = strstr(base, ".local");
if (ptr && strlen(ptr) == 6 && errsv != EACCES)
return;
fprintf(stderr, "Error: cannot access profile file: %s\n", fname);
exit(1);
}

The issues seems to be that include foobar first tries ~/.config/firejail and /etc/firejail. If foobar is not found there, it is looked up in CWD. But the call to access returns EPERM (or something else but not EACCES).

EDIT: Reason for failing on EPERM: #3478 (comment) and all following.

@oliversturm
Copy link
Author

To confirm, when I mount gocryptfs with allow_other, the problem goes away. And... here's your code snippet. Yeah, that explains it.

@oliversturm
Copy link
Author

I don't entirely agree with this comment:

I think if a .local file exists but has wrong permissions, we should also exit, so the user can fix it.

I think it would be better if we don't exit if a .local file is found (or not) with inaccessible permissions. As this issue illustrates, there could be more than one reason for this, including the case where the current working directory can't even be accessed at all.

@rusty-snake
Copy link
Collaborator

I want to keep failing on EPERM, since it indicates invalid/wrong configurations. However, include does not need to lookup in cwd IMHO. I mean as long as /etc/firejail and ~/.config/firejail has a higher order, there is no good reason to look in cwd for a included profile (--profile and --include should look in cwd).

@oliversturm
Copy link
Author

include does not need to lookup in cwd

I agree with that - I thought this behavior was "on purpose". I think it could be potentially dangerous to check cwd for an include instruction found in the main profile, because I may not realize that the cwd contains a .local override file and I'm executing a command with a "special" configuration.

@rusty-snake
Copy link
Collaborator

potentially dangerous

A program in a blacklisting sandbox could create it's own .local in cwd (usually ~) and add read-write ${HOME}/.bashrc. After the next start, it can write to ~/.bashrc. However this does not work for whitelisting profiles, and blacklisting profiles can be escapes by just creating .config/{systemd,environmentd} for example. Those dirs are read on the most systemd and don't exists on the most systems.

@oliversturm
Copy link
Author

All agreed. I wasn't thinking in such detail - just that I could be enticed somehow to download a file called tar.local, and when I next use the tar command while in ~/Downloads, it would run with whatever profile modifications tar.local applies - without me noticing.

@hlein
Copy link
Contributor

hlein commented Dec 28, 2020

FWIW / for search engines' benefit, the same problem occurs running firejail while sitting in an encfs filesystem, probably the same reason (pwd is a fuse filesystem not mounted with allow_*, etc.).

@rusty-snake rusty-snake added the bug Something isn't working label Jan 4, 2021
@rusty-snake rusty-snake added this to the 0.9.65 milestone Jan 4, 2021
@mirko
Copy link

mirko commented Apr 7, 2021

Also for completion and for the next one having the same problem and searching for it immediately being suggested this issue ticket:
When an SMB share is being mounted via gnome/nautilus/gvfs - path being e.g. /run/user/1000/gvfs/smb-share:server=nas.local,share=data/ - the same issue occurs.

@ilikenwf
Copy link
Contributor

ilikenwf commented Aug 20, 2021

Also for completion and for the next one having the same problem and searching for it immediately being suggested this issue ticket:
When an SMB share is being mounted via gnome/nautilus/gvfs - path being e.g. /run/user/1000/gvfs/smb-share:server=nas.local,share=data/ - the same issue occurs.

Yes, this is my issue with opening files from Thunar - I can drag and drop them to open in VLC or an editor, however I can't whitelist the gvfs mount location because it is no longer in my home directory.

My only workaround so far has been to symlink directly in /usr/local/bin eog, vlc, geany, and others so I don't run into this.

@shaaati
Copy link

shaaati commented Jan 3, 2022

Also for completion and for the next one having the same problem and searching for it immediately being suggested this issue ticket:
When an SMB share is being mounted via gnome/nautilus/gvfs - path being e.g. /run/user/1000/gvfs/smb-share:server=nas.local,share=data/ - the same issue occurs.

This is super annoying. My NAS is pretty much unusable with a default firejail installation. I thought I could work around this by removing include evince.local from the profile but then it goes on: cannot acces globals.local, cannot access disable-common.local, ... and many more to come.

Does anyone have a suggestion how to efficiently make this work?

@rusty-snake
Copy link
Collaborator

AFAIK you can

  • touch all the .local files in a location with a higher priority (e.g. /etc/firejail)
  • run from a different CWD
  • mount with allow_root/allow_other
  • fix firejail

to workaround.

@shaaati
Copy link

shaaati commented Jan 3, 2022

AFAIK you can\n\ntouch all the .local files in a location with a higher priority (e.g. /etc/firejail)

That was a nice idea.
I created them by issuing for file in $(ls /etc/firejail); do touch /etc/firejail/$(echo $file | cut -d"." -f1).local; done (might not be the cleanest option, but it worked).

However, evince still fails to open the file. When opening a PDF using the GUI, evince shows the correct file path (/run/user/1000/gvfs/long/path/to/SMB/folder/filename.pdf), when opening a terminal in the same location, it shows /home/username/filename.pdf as the filename.

In both cases the file open fails with "file or directory not found". I suppose this is a privilege issue, too?

Running from another cwd as in "start evince in another directory than open the file which is still located on the share" fails with the same error message. Copying the file to another directory would of course work, but is not very efficient.
The same goes for "mount with options". Afaik, gvfs-mount does not really support the permanent configuration of custom mount options. So I would have to mount the SMB shares without gvfs, which would require a lot of re-configuration. I have set up multiple shares and am used to navigate them using gvfs.

Ultimately, I think that firejail should support gvfs shares out of the box if technically possible. This leaves "fix firejail" as only viable option, which I am unfortunately unable to do. However, I hope that my analysis can at least help others with the same issue.

@rusty-snake
Copy link
Collaborator

First you need to distinct different issues here:

  1. (this issue) Firejail looks for includes in the current working directory and fails if access fails with something else than EACCES. (fixable). This is why "running from a different cwd..."
  2. You try to open a file in a program (evince) but the profile does not allow access to this file. If this is more than whitelist ${RUNUSER}/gvfs it is better to discuss it in a new discussion.
  3. gvfs/FUSE mount without allow_root/allow_other where root (firejail) lacks permission to mount/access/... (not fixable at firejail's side).

@shaaati
Copy link

shaaati commented Jan 5, 2022

I understood this issue to be more about the allow_root/allow_other mount option of fuse file systems, which is why I kept posting here.

To sum it up, I tried adding whitelist ${RUNUSER}/gvfs and it still doesn't work, but the error message changed. Now firejail prints something like "whitelist_file: Permission denied".

I don't understand how my situation differs from the apparently working example described in #3798 (comment), which is why I thought that there must be some other problem. It seems however that it ultimately all comes down to allow_root/allow_other.

Thanks for your help anyway, I will try to evaluate some alternatives. I still consider mounting SMB shares via gvfs something that many Linux users might do, so it would be great to come up with a way to make this work with firejail.

Edit:
If anyone else is facing the same problem, a possible workaround is described in https://askubuntu.com/questions/401454. I adapted it a bit to make it work on my system. In essence:

  • edit /etc/fuse.conf so that it contains the line user_allow_other
  • create a file /home//fuse-remount.desktop with content:
[Desktop Entry]
Version=1.0
Type=Application
Name=Fuse Remount
Terminal=false
Exec=sh -c "fusermount -zu /run/user/<userid>/gvfs && /usr/libexec/gvfsd-fuse -o allow_root /run/user/<userid>/gvfs"
  • do not forget to whitelist the gvfs path, e.g., by creating the file /etc/firejail/whitelist-runuser-common.local and putting the line whitelist ${RUNUSER}/gvfs in it.

The next time you login, the autostart script should fire and remount the gvfs fuse file system with the crucial allow_root option. Note that on my Fedora system, the path for gvfsd-fuse differed from the one mentioned in the askubuntu post. This might be distribution specific.

@hlein
Copy link
Contributor

hlein commented Jan 9, 2022

I want to keep failing on EPERM, since it indicates invalid/wrong configurations. However, include does not need to lookup in cwd IMHO. I mean as long as /etc/firejail and ~/.config/firejail has a higher order, there is no good reason to look in cwd for a included profile (--profile and --include should look in cwd).

I would agree with not searching cwd (creates concerns similar to having . in PATH). I've also encountered something related: if I have a fuse filesystem mounted without user_allow_other anywhere under my homedir, then firejail for various commands fails with the cannot access profile file: globals.local error or similar regardless of my cwd. I did not dig in deeply at the time - just umounted/remounted those fuse filesystems and moved on.

If firejail only looked in /etc/firejail/ and ~/.config/firejail/, seems there would be fewer surprises.

@kmk3
Copy link
Collaborator

kmk3 commented Jan 9, 2022

@hlein commented on Jan 9:

I want to keep failing on EPERM, since it indicates invalid/wrong
configurations. However, include does not need to lookup in cwd IMHO. I
mean as long as /etc/firejail and ~/.config/firejail has a higher order,
there is no good reason to look in cwd for a included profile (--profile
and --include should look in cwd).

I would agree with not searching cwd (creates concerns similar to having .
in PATH). I've also encountered something related: if I have a fuse
filesystem mounted without user_allow_other anywhere under my homedir,
then firejail for various commands fails with the cannot access profile file: globals.local error or similar regardless of my cwd. I did not dig in
deeply at the time - just umounted/remounted those fuse filesystems and moved
on.

If firejail only looked in /etc/firejail/ and ~/.config/firejail/, seems
there would be fewer surprises.

I agree with not searching . by default. If the use case is testing many
profile files on an isolated directory, maybe firejail could have an -I flag
to add include paths (like the -I C preprocessor flag). Example:

$ cat foo.profile
include bar.profile
$ firejail -I. --profile=foo.profile --include=bar.profile ./foo

This would include ./foo.profile, ./bar.profile and then run ./foo.

@kmk3 kmk3 changed the title Can't start firejailed app from a path on a gocryptfs filesystem Cannot start firejailed app from a path on a gocryptfs filesystem Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

8 participants