[GH-ISSUE #2100] seccomp filtering not working with chroot #1420

Closed
opened 2026-05-05 08:05:13 -06:00 by gitea-mirror · 7 comments
Owner

Originally created by @reinerh on GitHub (Aug 29, 2018).
Original GitHub issue: https://github.com/netblue30/firejail/issues/2100

Originally assigned to: @netblue30 on GitHub.

The Debian security team received a report that using --seccomp together with --chroot does not work as one would expect.
If the libpostexecseccomp.so library is missing inside the chroot, the syscalls are not actually filtered.

For example:

$ touch /srv/chroot/autopkgtest/tmp/foo
$ ls -l /srv/chroot/autopkgtest/tmp/foo
-rw-r--r-- 1 reiner reiner 0 Aug 29 18:11 /srv/chroot/autopkgtest/tmp/foo
$ firejail --seccomp.drop=unlinkat --chroot=/srv/chroot/autopkgtest rm /tmp/foo
Warning: default profile disabled by --chroot option
Parent pid 13096, child pid 13097
Warning: cannot find home directory
Dropping all Linux capabilities and enforcing default seccomp filter
Warning: failed to unmount /sys
Post-exec seccomp protector enabled
Child process initialized in 4.49 ms
ERROR: ld.so: object '/usr/lib/x86_64-linux-gnu/firejail/libpostexecseccomp.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/usr/lib/x86_64-linux-gnu/firejail/libpostexecseccomp.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.

Parent is shutting down, bye...
$ ls -l /srv/chroot/autopkgtest/tmp/foo
ls: cannot access '/srv/chroot/autopkgtest/tmp/foo': No such file or directory

As firejail is already checking that a certain directory hierarchy is present inside the chroot (/dev, /etc, /var/tmp, ...), it should also check that the required libraries it (pre)loads are there.
It should also be documented how the chroot should look like if one wants to use all firejail features.

Originally created by @reinerh on GitHub (Aug 29, 2018). Original GitHub issue: https://github.com/netblue30/firejail/issues/2100 Originally assigned to: @netblue30 on GitHub. The Debian security team received a report that using `--seccomp` together with `--chroot` does not work as one would expect. If the libpostexecseccomp.so library is missing inside the chroot, the syscalls are not actually filtered. For example: ``` $ touch /srv/chroot/autopkgtest/tmp/foo $ ls -l /srv/chroot/autopkgtest/tmp/foo -rw-r--r-- 1 reiner reiner 0 Aug 29 18:11 /srv/chroot/autopkgtest/tmp/foo $ firejail --seccomp.drop=unlinkat --chroot=/srv/chroot/autopkgtest rm /tmp/foo Warning: default profile disabled by --chroot option Parent pid 13096, child pid 13097 Warning: cannot find home directory Dropping all Linux capabilities and enforcing default seccomp filter Warning: failed to unmount /sys Post-exec seccomp protector enabled Child process initialized in 4.49 ms ERROR: ld.so: object '/usr/lib/x86_64-linux-gnu/firejail/libpostexecseccomp.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored. ERROR: ld.so: object '/usr/lib/x86_64-linux-gnu/firejail/libpostexecseccomp.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored. Parent is shutting down, bye... $ ls -l /srv/chroot/autopkgtest/tmp/foo ls: cannot access '/srv/chroot/autopkgtest/tmp/foo': No such file or directory ``` As firejail is already checking that a certain directory hierarchy is present inside the chroot (/dev, /etc, /var/tmp, ...), it should also check that the required libraries it (pre)loads are there. It should also be documented how the chroot should look like if one wants to use all firejail features.
gitea-mirror 2026-05-05 08:05:13 -06:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@smitsohu commented on GitHub (Aug 30, 2018):

I was also thinking if we maybe can expect from users to actually turn chroot on in firejail.config (and ship firejail with it turned off by default). That's a different topic though.

<!-- gh-comment-id:417277267 --> @smitsohu commented on GitHub (Aug 30, 2018): I was also thinking if we maybe can expect from users to actually turn chroot on in firejail.config (and ship firejail with it turned off by default). That's a different topic though.
Author
Owner

@netblue30 commented on GitHub (Aug 30, 2018):

It is a different bug! By default for --chroot, --overlay-* and --appimage we do the following:

  1. set nonewprivs flag in the kernel
  2. disregard user capabilities configuration and drop all of them
  3. disregard the user seccomp configuration and enforce the default seccomp filter

If any of these fail, we don't start the sandbox. For example it will fail on kenel 3.2 where there is no seccomp available. For --chroot sandboxes seccomp will always run. This can be easily checked from firetools or with --seccomp.print. Example:

$ firejail --name=test --seccomp.drop=unlinkat --chroot=/chroot/sid
Warning: default profile disabled by --chroot option
Parent pid 8766, child pid 8767
Dropping all Linux capabilities and enforcing default seccomp filter
Post-exec seccomp protector enabled
Child process initialized in 5.79 ms
ERROR: ld.so: object '/usr/lib/firejail/libpostexecseccomp.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/usr/lib/firejail/libpostexecseccomp.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
ERROR: ld.so: object '/usr/lib/firejail/libpostexecseccomp.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.

In a different terminal I check the test sandbox:

$ firejail --seccomp.print=test
Switching to pid 8767, the first child process inside the sandbox
 line  OP JT JF    K
=================================
 0000: 20 00 00 00000004   ld  data.architecture
 0001: 15 01 00 c000003e   jeq ARCH_64 0003 (false 0002)
 0002: 06 00 00 7fff0000   ret ALLOW
 0003: 20 00 00 00000000   ld  data.syscall-number
 0004: 35 01 00 40000000   jge X32_ABI 0006 (false 0005)
 0005: 35 01 00 00000000   jge read 0007 (false 0006)
 0006: 06 00 00 00050001   ret ERRNO(1)
 0007: 15 41 00 0000009a   jeq modify_ldt 0049 (false 0008)
 0008: 15 40 00 000000d4   jeq lookup_dcookie 0049 (false 0009)
 0009: 15 3f 00 0000012a   jeq perf_event_open 0049 (false 000a)
 000a: 15 3e 00 00000137   jeq process_vm_writev 0049 (false 000b)
 000b: 15 3d 00 0000009c   jeq _sysctl 0049 (false 000c)
 000c: 15 3c 00 000000b7   jeq afs_syscall 0049 (false 000d)
 000d: 15 3b 00 000000ae   jeq create_module 0049 (false 000e)
 000e: 15 3a 00 000000b1   jeq get_kernel_syms 0049 (false 000f)
 000f: 15 39 00 000000b5   jeq getpmsg 0049 (false 0010)
 0010: 15 38 00 000000b6   jeq putpmsg 0049 (false 0011)
 0011: 15 37 00 000000b2   jeq query_module 0049 (false 0012)
 0012: 15 36 00 000000b9   jeq security 0049 (false 0013)
 0013: 15 35 00 0000008b   jeq sysfs 0049 (false 0014)
 0014: 15 34 00 000000b8   jeq tuxcall 0049 (false 0015)
 0015: 15 33 00 00000086   jeq uselib 0049 (false 0016)
[...]

We have two bugs:

  1. Document everything in the man pages

  2. Get rid of the ld.so messages. Somehow the sandbox still tries to install the postexec seccomp filter, but this filter is an empty file (it was replaced by the regular seccomp filter), and the postexec loader is missing anyway.

I'll bring in the fixes.

<!-- gh-comment-id:417299723 --> @netblue30 commented on GitHub (Aug 30, 2018): It is a different bug! By default for --chroot, --overlay-* and --appimage we do the following: 1. set nonewprivs flag in the kernel 2. disregard user capabilities configuration and drop all of them 3. disregard the user seccomp configuration and enforce the default seccomp filter If any of these fail, we don't start the sandbox. For example it will fail on kenel 3.2 where there is no seccomp available. For --chroot sandboxes seccomp will always run. This can be easily checked from firetools or with --seccomp.print. Example: ````` $ firejail --name=test --seccomp.drop=unlinkat --chroot=/chroot/sid Warning: default profile disabled by --chroot option Parent pid 8766, child pid 8767 Dropping all Linux capabilities and enforcing default seccomp filter Post-exec seccomp protector enabled Child process initialized in 5.79 ms ERROR: ld.so: object '/usr/lib/firejail/libpostexecseccomp.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored. ERROR: ld.so: object '/usr/lib/firejail/libpostexecseccomp.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored. ERROR: ld.so: object '/usr/lib/firejail/libpostexecseccomp.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored. ````` In a different terminal I check the test sandbox: ````` $ firejail --seccomp.print=test Switching to pid 8767, the first child process inside the sandbox line OP JT JF K ================================= 0000: 20 00 00 00000004 ld data.architecture 0001: 15 01 00 c000003e jeq ARCH_64 0003 (false 0002) 0002: 06 00 00 7fff0000 ret ALLOW 0003: 20 00 00 00000000 ld data.syscall-number 0004: 35 01 00 40000000 jge X32_ABI 0006 (false 0005) 0005: 35 01 00 00000000 jge read 0007 (false 0006) 0006: 06 00 00 00050001 ret ERRNO(1) 0007: 15 41 00 0000009a jeq modify_ldt 0049 (false 0008) 0008: 15 40 00 000000d4 jeq lookup_dcookie 0049 (false 0009) 0009: 15 3f 00 0000012a jeq perf_event_open 0049 (false 000a) 000a: 15 3e 00 00000137 jeq process_vm_writev 0049 (false 000b) 000b: 15 3d 00 0000009c jeq _sysctl 0049 (false 000c) 000c: 15 3c 00 000000b7 jeq afs_syscall 0049 (false 000d) 000d: 15 3b 00 000000ae jeq create_module 0049 (false 000e) 000e: 15 3a 00 000000b1 jeq get_kernel_syms 0049 (false 000f) 000f: 15 39 00 000000b5 jeq getpmsg 0049 (false 0010) 0010: 15 38 00 000000b6 jeq putpmsg 0049 (false 0011) 0011: 15 37 00 000000b2 jeq query_module 0049 (false 0012) 0012: 15 36 00 000000b9 jeq security 0049 (false 0013) 0013: 15 35 00 0000008b jeq sysfs 0049 (false 0014) 0014: 15 34 00 000000b8 jeq tuxcall 0049 (false 0015) 0015: 15 33 00 00000086 jeq uselib 0049 (false 0016) [...] ````` We have two bugs: 1. Document everything in the man pages 2. Get rid of the ld.so messages. Somehow the sandbox still tries to install the postexec seccomp filter, but this filter is an empty file (it was replaced by the regular seccomp filter), and the postexec loader is missing anyway. I'll bring in the fixes.
Author
Owner

@reinerh commented on GitHub (Aug 30, 2018):

@netblue30 I think firejail shouldn't start the program if it was explicitely requested that some syscalls are dropped, instead of running it with default filters.

<!-- gh-comment-id:417381661 --> @reinerh commented on GitHub (Aug 30, 2018): @netblue30 I think firejail shouldn't start the program if it was explicitely requested that some syscalls are dropped, instead of running it with default filters.
Author
Owner

@netblue30 commented on GitHub (Sep 1, 2018):

It won't work. Most of the time the user has no idea where the filters are coming from (profile files), and some profiles are modifying the seccomp filter. For example in --overlay and --appimage (firejail --overlay firefox). It is better just to leave it running and put a big message on the screen, something like this:

$ firejail --chroot=/chroot/sid
Warning: default profile disabled by --chroot option
Parent pid 7994, child pid 7995

** Warning: dropping all Linux capabilities and enforcing  **
**                  default seccomp filter                 **

Child process initialized in 5.26 ms

I removed libpostexec.so functionality and modified the man pages: 07384ab64a

I'll do some testing over the weekend, probably there is more to come.

<!-- gh-comment-id:417854774 --> @netblue30 commented on GitHub (Sep 1, 2018): It won't work. Most of the time the user has no idea where the filters are coming from (profile files), and some profiles are modifying the seccomp filter. For example in --overlay and --appimage (firejail --overlay firefox). It is better just to leave it running and put a big message on the screen, something like this: ````` $ firejail --chroot=/chroot/sid Warning: default profile disabled by --chroot option Parent pid 7994, child pid 7995 ** Warning: dropping all Linux capabilities and enforcing ** ** default seccomp filter ** Child process initialized in 5.26 ms ````` I removed libpostexec.so functionality and modified the man pages: https://github.com/netblue30/firejail/commit/07384ab64a4a98ff920e7667795282ae9ad21322 I'll do some testing over the weekend, probably there is more to come.
Author
Owner

@netblue30 commented on GitHub (Sep 1, 2018):

OK, this is another bug: default profiles are not applied by default for --chroot. Fix in ba2e5f55ed

$ firejail --chroot=/chroot/sid
Reading profile /etc/firejail/default.profile
Reading profile /etc/firejail/globals.local
Reading profile /etc/firejail/disable-common.inc
Reading profile /etc/firejail/disable-passwdmgr.inc
Reading profile /etc/firejail/disable-programs.inc

** Note: you can use --noprofile to disable default.profile **

Warning: --chroot and --noroot are mutually exclusive, noroot disabled
Parent pid 19028, child pid 19029

** Warning: dropping all Linux capabilities and enforcing  **
**                  default seccomp filter                 **

Child process initialized in 23.15 ms
<!-- gh-comment-id:417858375 --> @netblue30 commented on GitHub (Sep 1, 2018): OK, this is another bug: default profiles are not applied by default for --chroot. Fix in https://github.com/netblue30/firejail/commit/ba2e5f55ed8b3bd83b15fc51ae5ef6050b8f8dca ````` $ firejail --chroot=/chroot/sid Reading profile /etc/firejail/default.profile Reading profile /etc/firejail/globals.local Reading profile /etc/firejail/disable-common.inc Reading profile /etc/firejail/disable-passwdmgr.inc Reading profile /etc/firejail/disable-programs.inc ** Note: you can use --noprofile to disable default.profile ** Warning: --chroot and --noroot are mutually exclusive, noroot disabled Parent pid 19028, child pid 19029 ** Warning: dropping all Linux capabilities and enforcing ** ** default seccomp filter ** Child process initialized in 23.15 ms `````
Author
Owner

@reinerh commented on GitHub (Sep 1, 2018):

Hm, I still think that firejail should not allow the program to run if the user explicitely requests for syscalls to be dropped (on the command line), but for some reason (also using --chroot) firejail would have to use the default seccomp filter (which would allow again the syscall that was requested to be dropped).

Maybe --seccomp.drop etc should be disallowed from using together with --chroot.

<!-- gh-comment-id:417893966 --> @reinerh commented on GitHub (Sep 1, 2018): Hm, I still think that firejail should not allow the program to run if the user explicitely requests for syscalls to be dropped (on the command line), but for some reason (also using `--chroot`) firejail would have to use the default seccomp filter (which would allow again the syscall that was requested to be dropped). Maybe `--seccomp.drop` etc should be disallowed from using together with `--chroot`.
Author
Owner

@netblue30 commented on GitHub (Sep 3, 2018):

Done! (55cd5c1d8f)

I'll be doing more testing and cleanup this week. This is what I have for chroot in this moment:

  • if seccomp.drop, seccomp.keep or seccomp= is configured on command line we don't start the sandbox

  • if seccomp.drop, seccomp,keep or seccomp= is configured in a profile file, we replace the filter, print a big warning on the screen, and start the sandbox

  • protocol, seccomp.block-secondary and memory-deny-write-execute are handled independently and are not affected

Similar scheme is in effect for caps command line options under chroot.

<!-- gh-comment-id:418110716 --> @netblue30 commented on GitHub (Sep 3, 2018): Done! (https://github.com/netblue30/firejail/commit/55cd5c1d8f4007bc28d50c4324d2f1ff8dbef14a) I'll be doing more testing and cleanup this week. This is what I have for chroot in this moment: * if seccomp.drop, seccomp.keep or seccomp= is configured on command line we don't start the sandbox * if seccomp.drop, seccomp,keep or seccomp= is configured in a profile file, we replace the filter, print a big warning on the screen, and start the sandbox * protocol, seccomp.block-secondary and memory-deny-write-execute are handled independently and are not affected Similar scheme is in effect for caps command line options under chroot.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: github-starred/firejail#1420
No description provided.