netblue30 / firejail

Linux namespaces and seccomp-bpf sandbox
https://firejail.wordpress.com
GNU General Public License v2.0
5.55k stars 557 forks source link

Hiding HOME with --whitelist: cannot open directory '.' #2114

Open onlyjob opened 5 years ago

onlyjob commented 5 years ago

I'm trying to hide contents of HOME directory from jailed application using --whitelist option as described in #583:

firejail --whitelist=/home/user/tmp_ bash

However instead of empty home with tmp_ folder in it I get ls: cannot open directory '.': Permission denied when I try ls in user's home directory (ls tmp_ works):

$ firejail --noprofile --whitelist=$(readlink -f $HOME/tmp_) bash -c 'ls'
Parent pid 143110, child pid 143111
Child process initialized in 25.74 ms
ls: cannot open directory '.': Permission denied

Parent is shutting down, bye...

What is the recommended way to jail application in a fake user's home to hide certain locations that application have no business accessing?

firejail version 0.9.54

Thanks.

smitsohu commented 5 years ago

Could you please re-run this command with --debug-whitelists?

onlyjob commented 5 years ago

Thank you.

$ firejail --noprofile --debug-whitelists --whitelist=$(readlink -f $HOME/tmp_) bash -c 'ls'
Parent pid 123974, child pid 123975
Debug 424: new_name #/mnt/r/home/user/tmp_#, whitelist
real path /mnt/r/home/user/tmp_
Mounting tmpfs on /mnt directory
Whitelisting /mnt/r/home/user/tmp_
Child process initialized in 53.73 ms
ls: cannot open directory '.': Permission denied

Parent is shutting down, bye...

/home/user is a symlink: /home/user -> /mnt/r/home/user.

I think the Mounting tmpfs on /mnt directory in the output looks suspicious and possibly suggests a bug in the assumption that user's home is two levels deep from the root?

smitsohu commented 5 years ago

Hmmm. I have trouble reproducing your issue. I created a new user, let's call him tester, a symbolic link /home/tester -> /mnt/bla/tester, and two files /mnt/bla/tester/abc and xyz. This is what I get:

tester@smitsohu:~$ firejail --noprofile --whitelist=$(readlink -f $HOME/abc) bash -c 'ls'
Parent pid 9015, child pid 9016
Child process initialized in 29.38 ms
abc

Parent is shutting down, bye...

Are you doing something special, maybe with FUSE?

onlyjob commented 5 years ago

But in my case tmp_ is a directory... Yes, users' homes are on FUSE, /mnt/r is FUSE-mounted.

smitsohu commented 5 years ago

Probably this is caused by FUSE. The underlying reason is that when it comes to FUSE, even the powers of the root user are limited, and Firejail needs root for setting up the sandbox.

What you could try is mounting users' homes with allow_other or allow_root option, depending on who is doing the mount, root or regular user.

For comparing there are a number of similar issues, for instance #1560, but the behavior of whitelisting has changed slightly in the meantime, so you won't be able to reproduce all examples exactly.

onlyjob commented 5 years ago

I did not expect any problems with FUSE because it is mounted by root with user_allow_other. We have all users' homes on network share and mount point already have allow_other...

smitsohu commented 5 years ago

Ok, then it must be something else. Are you maybe employing NFS?

onlyjob commented 5 years ago

If it were NFS I would probably had it mounted using kernel client rather than through FUSE... ;)

We are using LizardFS - distributed parallel file system. It have built-in data integrity, no single point of failure, good performance, etc.

smitsohu commented 5 years ago

I see. Maybe someone else with an idea?

rusty-snake commented 5 years ago

@onlyjob does --private=~/tmp_ or --private-home=tmp_ work for you. Note: that they don't do exactly the same.

rusty-snake commented 4 years ago

I'm closing here due to inactivity, please fell free to reopen if you still have this issue.

onlyjob commented 4 years ago

Sorry I could not get to this issue earlier. I have upgraded my system to Debian 10 "buster" and firejail version 0.9.58.2.

--private=~/tmp_ is not what I need;
--private-home=tmp_ appears to behave similar to --whitelist=~/tmp_ but warns: Error fcopy: size limit of 500MB reached.

The original problem with --whitelist=~/tmp_ is gone.
However with symlinked home directory firejail still does not work properly by default:

$ ls -l ~
/home/user -> /mnt/r/home/user

$ pwd
/home/user

$ firejail --whitelist=~/tmp_ bash
$ pwd
/mnt/r/home/user

Note how under Firejail current working directory changed to /mnt/r/home/user and ls still show all files in the home directory unless I cd ~ under firejail.

For me the correct invocation of firejail is

firejail --whitelist=~/tmp_ --whitelist=$(readlink -f ~)/tmp_  bash

to hide symlinked home so I recommend to have a special workaround for symlinked home directories by default.

P.S. I can not "reopen" the ticket. There is only "Comment" button...

smitsohu commented 4 years ago

Not sure what your current Firejail version is, but as an outlook, the treatment of home directories outside of /home has changed in current master....

There should be now full support for whitelisting and everything else, with all bells and whistles and no need for workarounds. However, there is still a problem if the user's entry in the system password database (/etc/passwd usually) does not contain the resolved path to the home directory, but a path with a symbolic link.

In this case all we can do currently (in master) is ask the user/administrator to update the password database and provide a fully resolved path there. Once this is done, there should be no outstanding issues (in master).

smitsohu commented 4 years ago

--private-home=tmp appears to behave similar to --whitelist=~/tmp but warns: Error fcopy: size limit of 500MB reached.

In current master that limit is configurable in /etc/firejail/firejail.config

onlyjob commented 4 years ago

I think firejail should always normalise user's HOME path with readlink -f. In our case use of symlinks is intentional. Basically this issue could be considered a vulnerability as without special workaround it is trivial to bypass firejail isolation by merely a symlink.

I wonder is --bind mount should be detected also?

smitsohu commented 4 years ago

I think firejail should always normalise user's HOME path with readlink -f

Yeah, this was the original plan. But as user directories literally can be everywhere, there is the unlikely but not inconceivable case where a user is able to control the readlink return value (using a symbolic link to trick Firejail into thinking the user directory is somewhere else). Because of this, Firejail trusts only the raw string extracted from /etc/passwd, which is guaranteed to be under control of root.

In our case use of symlinks is intentional.

You can continue using them. But now that you mention it, I realize Firejail does not create a full representation of the file system inside the sandbox, in that a symbolic link in /home would be absent inside the sandbox. Maybe we should detect this situation.

I wonder is --bind mount should be detected also?

They tend to be less problematic from a privilege management perspective, as FUSE and friends guarantee to not increase DAC permissions, and they require CAP_SYS_ADMIN. So instead of using a symbolic link, you can always also bind-mount. Generally speaking, mounts are less problematic for Firejail than symbolic links.