mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 14:16:14 -06:00
[GH-ISSUE #565] Some firejailed processes join an unsandboxed parent instance #397
Labels
No labels
LTS merge
LTS merge
bug
bug
converted-to-discussion
doc-todo
documentation
duplicate
enhancement
file-transfer
firecfg
firejail-in-firejail
firetools
graphics
help wanted
information_old
installation
invalid
modif
moved
needinfo
networking
notabug
notourbug
old-version
overlayfs
packaging
profile-request
pull-request
question
question_old
removal
runtime-permissions
sandbox-ipc
security
stale
wiki
wiki
wontfix
wordpress
workaround
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: github-starred/firejail#397
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Sidnioulz on GitHub (Jun 11, 2016).
Original GitHub issue: https://github.com/netblue30/firejail/issues/565
Many apps use various hacks to ensure they have a single instance running. Which of course is a problem for sandboxes. There are two common cases: files and DBus.
Blocking PID files
For files, apps write to a specific file to indicate they're running (with a PID / path to a UDS to contact the current instance), which needs to be hidden in the sandbox, and this could simply be a "blacklist" line in the profile.
It sometimes happens that apps require these files for a good reason. They might not support multiple instances changing the settings or cache. So there should also be a way to state that the app's config folders should be mount-bind'ed or overlayfs'ed to prevent conflicts.
Alternatively, Firejail could be made to refuse to run an app if the existing filesystem options expose the path of the PID file. For instance, if I run "firejail firefox", and firejail reads that $HOME/.firefox.lock is the PID file, Firejail could refuse to run unless I have specified something like --private-home or --overlay or --overlay-private-home (on my fork), which means the user knows the sandboxed instance is not conflicting with the unsandboxed one for config/cache file usage. In my GUI I almost always use filesystem options so that's fine by me.
Blocking DBus
For DBus, some apps rely on DBus sockets, so they need to be run in dbus-run-session. Inside the sandbox, Firejail could check if it is already running in a DBus session (check if any of your parents is dbus-run-session or dbus-daemon), and then just continue, or it could wrap the call in a dbus-run-session if necessary for the app.
In the future, it might be possible to do access control on specific DBus names, but I suspect this is not ready / easy yet. It is an intended feature of kdbus though and worth looking into.
Also note that if you implement support for DBus sessions, basically this is how it works:
I support DBus isolation in my fork, though my code is super messy (poor architectural choices in my early hacking which carried on), but maybe you can selectively steal code before I get to rebase.
I call this function right before join_namespace() in join.c. This ensures the DBus environment variable is set properly.
I support DBus with this code in main.c. My firejail.h contains
In sandbox.c, I wrap the call to Firejail when necessary (see also L295 and L331) and I blacklist the original DBus socket path.
Of course I also edit usage.c.
If there was support for these options in Firejail profiles (along with the possibility for explicitly forcing dbus on or forcing the PID file to be visible, with arguments), Firejail could be a lot more secure by default, by preventing those pesky apps from escaping. This is especially useful for people who wrap their Firejail calls and open GUI apps, since current DEs don't provide unique decorations to help identify sandboxed apps.
@netblue30 commented on GitHub (Jun 11, 2016):
Thanks for the writeup. I intend to merge in your dbus code. I'll give it a try next week!
@netblue30 commented on GitHub (Jul 10, 2016):
I ended up implementing --rmenv option:
I don't think you can blacklist the dbus socket, at least on Debian/Ubuntu computers it is an abstract socket. You can only get rid of it using a new network namespace (--net=eth0 or --net=none).
@Sidnioulz commented on GitHub (Aug 21, 2017):
I realise I'm doing necromancy by replying so late, but I had originally tested my code specifically with Ubuntu systems. You're correct that there are multiple methods used to expose the socket though. I would suggest having a quick chat with the DBus developers on their IRC channel to validate your solution.
IIRC, the problem with simply removing the DBus environment variable rather than wrapping in a new session is that some applications will try to use a default path for the address when no environment variable, which may point to the actual socket (which is still open) when stored in /run/user//bus (e.g. on ArchLinux).