mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 14:16:14 -06:00
[GH-ISSUE #3685] Warn on static binaries + seccomp #2321
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#2321
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 @commial on GitHub (Oct 22, 2020).
Original GitHub issue: https://github.com/netblue30/firejail/issues/3685
Hi there,
From what I understand on how firejail is working:
Long story short, to
seccompsystem call such asexecve, firejail is injecting code throughLD_PRELOADmechanism.As a result, for static binaries, this is ignored, and the resulting process will be able to
execve.It would be nice to have a warning that the
seccompwill not be honored, or even an opt-in option to avoid these behavior (ie. exit instead of launch the binary), for use cases where Firejail is use to sandboxed untrusted binaries.I don't know if another mechanism (like using
ptrace) could be used to actually circumvent this behavior.To reproduce:
@topimiettinen commented on GitHub (Oct 22, 2020):
Right. I think warning in documentation and at runtime would be appropriate.
Perhaps the problem could be avoided if Firejail executed in these cases a custom loader, which would set up the seccomp filter and then loaded the actual binary like kernel would do for static executables. That couldn't be bypassed.
@commial commented on GitHub (Oct 23, 2020):
Thanks for your quick answer.
From what I understand, the only seccomp "post-exec" syscalls are the one from "@default-keep":
Which resolves to:
Another way to convince ourselves is to ask
firejaildirectly:We can also write a tiny program to check for
prctl:And again:
So, the problem is for, and only for,
prctlandexecve.The custom-loader solution seems a bit overkill to me, and could actually lead to more problems (ELF parsing, etc.).
I've tried to look how others solutions circumvent this problem. From what I understand,
systemdactually disallow (in the sense: "will always fail") seccomp-ingexecve: (from the man page)It seems to me that the
prctlis kept post-exec to be able to later seccompexecve. But ifexecveis not expected to be seccomp-ed,prctlcould be actually done before theexecve, and then working for static binaries. IMHO, that would allow a reduction of a significant attack surface, givenprctlpossibilities. Am I missing something?As a side note:
From what I understand, to be able to seccomp
execve, one needs to allow some others syscalls, specifically the ones used by the loader andlibpostexecseccomp. These syscalls includes, for instance,openat,lseek,mmap,close, ...In such a case, what would be the expected behavior/use case? Disallowing
execvebut keeping a lot of likely dangerous syscalls (openat+mmapcould almost load an external binary)? (I don't have the answer)@topimiettinen commented on GitHub (Oct 24, 2020):
I agree that when
prctl()needs to be filtered but notexecve(), there shouldn't be a need to uselibpostexecseccomp.Filtering
openetc indeed breaks a lot of stuff (for example in the dynamic loader beforelibpostexecseccompis loaded), so perhaps the list should be more complete.prctl()is needed to install the seccomp filters but it's indeed not the only one.Systemd and Firejail have different approaches. Systemd is running as PID 1 which is about the most important piece of software in a system besides the kernel, so it's natural that features which could be considered too "hacky" are not very interesting. Firejail instead is in much more flexible position, it's OK if something doesn't work in every case since the feature can be often disabled via per application profiles. In the worst case it's always possible not to use Firejail, but switching PID 1 software (or not using any,
init=/bin/sh?) is much more difficult. Blockingexecve()with a ld.preload hack would not be OK for PID1, but it's an interesting option for Firejail.It's of course possible to circumvent blocked
execve()with use of other system calls. In the extreme case (fileless malware) attackers don't even needexecve()oropen()+mmap(), if they only chain enough ROP gadgets to build a simple remote shell or whatever they want to execute.I think a custom preloader (which wouldn't have to replace the real dynamic loader) could be interesting for other clever uses, after
execve()there could be further opportunities for sandboxing. For example, seccomp actionsSECCOMP_RET_TRAPandSECCOMP_RET_USER_NOTIFcall a function within the thread making the system call, but this could be supplied by the preloader. A custom preloader would be overkill for blockingexecve()just for statically linked applications but if it existed, Firejail would be able to install any seccomp filters, even for exampleSECCOMP_SET_MODE_STRICTwhich only allowsread,write,_exitandsigreturn.