netblue30 / firejail

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

vscode: cannot isolate sandboxes (RUNUSER socket) #3258

Closed pcrockett closed 4 years ago

pcrockett commented 4 years ago

I'm trying to create some general-purpose sandboxes. I have a work and a personal profile, and I launch them like this:

firejail --profile=work openbox &
firejail --profile=personal openbox &

The problem is that programs in my two sandboxes still seem to be able to interact.

  1. In personal openbox instance, launch VSCodium. It runs, and everything looks ok so far.
  2. In work openbox instance, also launch VSCodium. A new window opens in my personal sandbox alongside the VSCodium instance that's already running there, not in my work sandbox.

VSCodium always seems to want to open new windows in the first environment it's started in, whether inside a sandbox or not. I'm not sure how VSCodium is working behind the scenes to be able to break out of its sandbox. How do I figure that out and fix it?

Here's my personal profile. My work profile is identical, except in a few places instead of "personal" it says "work".

# Copy/paste/modified from default.profile

# Persistent local customizations
include default.local
# Persistent global definitions
include globals.local

# generic gui profile
# depending on your usage, you can enable some of the commands below:

include disable-common.inc
# include disable-devel.inc
# include disable-interpreters.inc
include disable-passwdmgr.inc
# include disable-programs.inc
#include disable-xdg.inc

caps.drop all
ipc-namespace
netfilter
no3d
# nodbus
nodvd
nogroups
nonewprivs
noroot
# nosound
notv
# nou2f
# novideo
protocol unix,inet,inet6
seccomp
# shell none
x11

disable-mnt
private /home/phil/sandboxes/personal
# private-bin program
private-cache
private-dev
# private-etc none
# private-lib
private-tmp

# memory-deny-write-execute
# noexec /home/phil
noexec /tmp

net wlan0

hostname personal
machine-id
join-or-start personal
Vincent43 commented 4 years ago

nodbus

Try uncommenting it. You may also try whitelist things in ${RUNUSER}.

pcrockett commented 4 years ago

Unfortunately that seems to have no effect. Looks like VSCodium isn't using DBus for inter-process communication.

At least now I know what DBus is, and why I'd want to disable it!

What would whitelisting things in ${RUNUSER} achieve? I figured I'd need to blacklist stuff to get VSCodium to behave. And what specifically in ${RUNUSER} would I want to whitelist?

rusty-snake commented 4 years ago

Try

# wayland socket:
whitelist ${RUNUSER}/wayland-0
# Xauthority for Xorg-sessions started by gdm:
whitelist ${RUNUSER}/gdm/Xauthority
# pulseaudio
whitelist ${RUNUSER}/pulse
# DBus session-bus:
whitelist ${RUNUSER}/bus

What would whitelisting things in ${RUNUSER} achieve?

Only whitelisted files are visible.

pcrockett commented 4 years ago

Ok, I gave that a try. Interesting results:

rusty-snake commented 4 years ago

Perhaps I need to do an overlay file system for ${RUNUSER} or something?

Thats what whitelist ${RUNUSER}/foo does.

ls /run/user/1000
firejail --noprofile '--whitelist=${RUNUSER}/systemd' ls /run/user/1000
pcrockett commented 4 years ago

Oh I get it! That makes so much more sense then.

With that command, I get this error message:

Error: invalid whitelist path /run/user/1000/systemd

Not a terribly helpful error message I must say. The file does exist.

pcrockett commented 4 years ago

From the profile man page about the whitelist setting:

A temporary file system is mounted on the top directory, and the whitelisted files are mount-binded inside. Modifications to whitelisted files are persistent, everything else is discarded when the sandbox is closed. The top directory could be user home, /dev, /etc, /media, /mnt, /opt, /srv, /sys/module, /usr/share, /var, and /tmp.

So it looks like anything under /run can't be whitelisted. It does look like tmpfs will do the trick, but sadly that requires running as root. :slightly_frowning_face:

Vincent43 commented 4 years ago

I did decide to take a look in the /run/user/1000 directory and found some vscode-blah-blah-random-stuff.sock files

yeah, this is where it leaks.

So it looks like anything under /run can't be whitelisted. It does look like tmpfs will do the trick, but sadly that requires running as root. 🙁

/run can't be whitelisted but /run/user/1000/ can and this is what you want to do (unless you run some older version of firejail), post firejail --version.

pcrockett commented 4 years ago

firejail version 0.9.58.2

So about a year old. This is the latest that comes with Parrot OS. I'll try upgrading and report back.

pcrockett commented 4 years ago

Ok, I updated to the latest release (0.9.62) and kept getting the whitelist error message. But I tried something different this time: --whitelist=${RUNUSER}/*. That did the trick. My /run/user/1000 directory inside the sandbox is empty, and now VSCodium runs completely isolated instances in the correct sandboxes.

Here's my new full profile:

# Copy/paste/modified from default.profile

# Persistent local customizations
include default.local
# Persistent global definitions
include globals.local

# generic gui profile
# depending on your usage, you can enable some of the commands below:

include disable-common.inc
# include disable-devel.inc
# include disable-interpreters.inc
include disable-passwdmgr.inc
# include disable-programs.inc
#include disable-xdg.inc

caps.drop all
ipc-namespace
netfilter
no3d
nodbus
nodvd
nogroups
nonewprivs
noroot
# nosound
notv
# nou2f
# novideo
protocol unix,inet,inet6
seccomp
# shell none

disable-mnt
private /home/phil/sandboxes/personal
whitelist ${RUNUSER}/*
# private-bin program
private-cache
private-dev
# private-etc none
# private-lib
private-tmp

# memory-deny-write-execute
# noexec /home/phil
noexec /tmp

net wlan0

hostname personal
machine-id

xephyr-screen 1480x924
x11

join-or-start personal

Thanks all.

rusty-snake commented 4 years ago

But I tried something different this time: --whitelist=${RUNUSER}/*. That did the trick. My /run/user/1000 directory inside the sandbox is empty,

whitelist globbing is actually unsupported, once it is supported this will reintroduce this issue for you. IMHO something like whitelist ${RUNUSER}/__empty__ would be better.

smitsohu commented 4 years ago

How about adding blacklist ${RUNUSER}/vscode-* (assuming that's the path) to disable-programs.inc or a comparable place? This socket is possibly also a vector to escape from other sandboxes.

pcrockett commented 4 years ago

Since this is meant to be a general-purpose sandbox, and not specifically for VS Code, I guess I'd want to do just blacklist ${RUNUSER}, is that correct?

Question: Doesn't blacklisting a directory cause permission errors? Or would it simply cause the directory to appear empty?

Sorry, I'd just try it out, but my PC isn't within reach at the moment.

rusty-snake commented 4 years ago

Permission errors

pcrockett commented 4 years ago

👌 So it sounds like for my case, since I do want applications to be able to write to the directory without having an effect on other sandboxes, whitelist ${RUNUSER}/__empty__ is a better tool for the job that blacklist.

It would sure be nice if Firejail just had an empty-dir feature or something like that. Whitelisting a random file seems like a bit of a hack.

rusty-snake commented 4 years ago

@smitsohu in general I think that we should do more whitelisting in RUNUSER, but we can do this ATM only for gtk3 and cli programs.