[GH-ISSUE #3933] different seccomp behavior with and without arguments #2459

Closed
opened 2026-05-05 09:08:32 -06:00 by gitea-mirror · 5 comments
Owner

Originally created by @fissie on GitHub (Jan 30, 2021).
Original GitHub issue: https://github.com/netblue30/firejail/issues/3933

Bug and expected behavior
There is a discrepancy in behavior between when "seccomp" and "seccomp something" is used in the profile. It appears as if "seccomp" always defaults to killing the process on hitting the forbidden system call, while "seccomp !chroot" (for example) defaults to using EPERM. Not only is this confusing and undocumented (and per earlier discussion in my pull request #3930, also a bug).

Expected: the difference between "seccomp" and "seccomp !chroot" should only be that one syscall.
Observed: the difference is that all syscalls return, instead of killing the binary.

If I use "seccomp !chroot" and --seccomp-error-action=kill, then the behavior is identical (although the compiled seccomp code is different, but that's a result of the optimizer).

No profile and disabling firejail
No difference (see below)

Reproduce

  1. run $ firejail --audit --seccomp --noprofile echo blah
    checking syscalls: mount... umount2... ptrace... swapon... swapoff... init_module... delete_module... chroot... pivot_root... iopl... ioperm...

  2. run $ firejail --audit '--seccomp=!chroot' --seccomp-error-action=kill --noprofile echo blah
    GOOD: seccomp BPF enabled.
    checking syscalls: mount... umount2... ptrace... swapon... swapoff... init_module... delete_module... chroot...
    UGLY: chroot syscall permitted.
    pivot_root... iopl... ioperm...

  3. run $ firejail --audit '--seccomp=!chroot' --noprofile echo blah
    checking syscalls: mount...
    UGLY: mount syscall permitted.
    umount2...
    UGLY: umount2 syscall permitted.
    ptrace...
    UGLY: ptrace syscall permitted.
    swapon...
    UGLY: swapon syscall permitted.
    swapoff...

  4. Profit. Now the reality is that the syscalls in case 3 are not really permitted, because the audit binary only detects the killing case, and not the eperm case, but it shows the difference.

Environment
Gentoo, firejail version 0.9.64

debug output
$ firejail --debug --audit --seccomp --noprofile echo blah
...
 0007: 15 00 01 0000009f   jeq adjtimex 0008 (false 0009)
 0008: 06 00 00 00000001   ret KILL
 0009: 15 00 01 00000131   jeq clock_adjtime 000a (false 000b)
 000a: 06 00 00 00000001   ret KILL
 000b: 15 00 01 000000e3   jeq clock_settime 000c (false 000d)
 000c: 06 00 00 00000001   ret KILL
...

$ firejail --audit --debug '--seccomp=!chroot' --noprofile echo blah
...
 0005: 35 01 00 00000000   jge read 0007 (false 0006)
 0006: 06 00 00 00050001   ret ERRNO(1)
 0007: 15 00 01 000000a1   jeq chroot 0008 (false 0009)
 0008: 06 00 00 7fff0000   ret ALLOW
 0009: 15 00 01 0000009f   jeq adjtimex 000a (false 000b)
 000a: 06 00 00 00050001   ret ERRNO(1)
 000b: 15 00 01 00000131   jeq clock_adjtime 000c (false 000d)
 000c: 06 00 00 00050001   ret ERRNO(1)
...

$ firejail --debug --audit '--seccomp=!chroot' --seccomp-error-action=kill --noprofile echo blah'
...
 0009: 15 3f 00 0000009f   jeq adjtimex 0049 (false 000a)
 000a: 15 3e 00 00000131   jeq clock_adjtime 0049 (false 000b)
 000b: 15 3d 00 000000e3   jeq clock_settime 0049 (false 000c)
 000c: 15 3c 00 000000a4   jeq settimeofday 0049 (false 000d)
 000d: 15 3b 00 0000009a   jeq modify_ldt 0049 (false 000e)
...
 0048: 06 00 00 7fff0000   ret ALLOW
 0049: 06 00 01 00000000   ret KILL
...

Originally created by @fissie on GitHub (Jan 30, 2021). Original GitHub issue: https://github.com/netblue30/firejail/issues/3933 **Bug and expected behavior** There is a discrepancy in behavior between when "seccomp" and "seccomp something" is used in the profile. It appears as if "seccomp" always defaults to killing the process on hitting the forbidden system call, while "seccomp !chroot" (for example) defaults to using EPERM. Not only is this confusing and undocumented (and per earlier discussion in my pull request #3930, also a bug). Expected: the difference between "seccomp" and "seccomp !chroot" should only be that one syscall. Observed: the difference is that all syscalls return, instead of killing the binary. If I use "seccomp !chroot" and --seccomp-error-action=kill, then the behavior is identical (although the compiled seccomp code is different, but that's a result of the optimizer). **No profile and disabling firejail** No difference (see below) **Reproduce** 1. run $ firejail --audit --seccomp --noprofile echo blah checking syscalls: mount... umount2... ptrace... swapon... swapoff... init_module... delete_module... chroot... pivot_root... iopl... ioperm... 2. run $ firejail --audit '--seccomp=!chroot' --seccomp-error-action=kill --noprofile echo blah GOOD: seccomp BPF enabled. checking syscalls: mount... umount2... ptrace... swapon... swapoff... init_module... delete_module... chroot... UGLY: chroot syscall permitted. pivot_root... iopl... ioperm... 3. run $ firejail --audit '--seccomp=!chroot' --noprofile echo blah checking syscalls: mount... UGLY: mount syscall permitted. umount2... UGLY: umount2 syscall permitted. ptrace... UGLY: ptrace syscall permitted. swapon... UGLY: swapon syscall permitted. swapoff... 3. Profit. Now the reality is that the syscalls in case 3 are not really permitted, because the audit binary only detects the killing case, and not the eperm case, but it shows the difference. **Environment** Gentoo, firejail version 0.9.64 <details><summary> debug output </summary> ``` $ firejail --debug --audit --seccomp --noprofile echo blah ... 0007: 15 00 01 0000009f jeq adjtimex 0008 (false 0009) 0008: 06 00 00 00000001 ret KILL 0009: 15 00 01 00000131 jeq clock_adjtime 000a (false 000b) 000a: 06 00 00 00000001 ret KILL 000b: 15 00 01 000000e3 jeq clock_settime 000c (false 000d) 000c: 06 00 00 00000001 ret KILL ... $ firejail --audit --debug '--seccomp=!chroot' --noprofile echo blah ... 0005: 35 01 00 00000000 jge read 0007 (false 0006) 0006: 06 00 00 00050001 ret ERRNO(1) 0007: 15 00 01 000000a1 jeq chroot 0008 (false 0009) 0008: 06 00 00 7fff0000 ret ALLOW 0009: 15 00 01 0000009f jeq adjtimex 000a (false 000b) 000a: 06 00 00 00050001 ret ERRNO(1) 000b: 15 00 01 00000131 jeq clock_adjtime 000c (false 000d) 000c: 06 00 00 00050001 ret ERRNO(1) ... $ firejail --debug --audit '--seccomp=!chroot' --seccomp-error-action=kill --noprofile echo blah' ... 0009: 15 3f 00 0000009f jeq adjtimex 0049 (false 000a) 000a: 15 3e 00 00000131 jeq clock_adjtime 0049 (false 000b) 000b: 15 3d 00 000000e3 jeq clock_settime 0049 (false 000c) 000c: 15 3c 00 000000a4 jeq settimeofday 0049 (false 000d) 000d: 15 3b 00 0000009a jeq modify_ldt 0049 (false 000e) ... 0048: 06 00 00 7fff0000 ret ALLOW 0049: 06 00 01 00000000 ret KILL ... ``` </details>
gitea-mirror 2026-05-05 09:08:32 -06:00
  • closed this issue
  • added the
    bug
    label
Author
Owner

@topimiettinen commented on GitHub (Jan 30, 2021):

Could you test #3934?

<!-- gh-comment-id:770290431 --> @topimiettinen commented on GitHub (Jan 30, 2021): Could you test #3934?
Author
Owner

@fissie commented on GitHub (Jan 30, 2021):

Much better, but still some bit left. Now the output of all combinations is optimized and looks similar, and --seccomp and --seccomp=X gives the same output (with EPERM). However, with plain --seccomp still ignores --seccomp-error-action=kill and always goes for EPERM.

<!-- gh-comment-id:770293385 --> @fissie commented on GitHub (Jan 30, 2021): Much better, but still some bit left. Now the output of all combinations is optimized and looks similar, and --seccomp and --seccomp=X gives the same output (with EPERM). However, with plain --seccomp still ignores --seccomp-error-action=kill and always goes for EPERM.
Author
Owner

@topimiettinen commented on GitHub (Feb 1, 2021):

It looks like the pre-built filters (which always use the default error action) are used, there's a bug in a check.

<!-- gh-comment-id:770768569 --> @topimiettinen commented on GitHub (Feb 1, 2021): It looks like the pre-built filters (which always use the default error action) are used, there's a bug in a check.
Author
Owner

@topimiettinen commented on GitHub (Feb 1, 2021):

I think it should be fixed now, can you test again?

<!-- gh-comment-id:770811437 --> @topimiettinen commented on GitHub (Feb 1, 2021): I think it should be fixed now, can you test again?
Author
Owner

@fissie commented on GitHub (Feb 1, 2021):

Looks good now, thanks!

<!-- gh-comment-id:770975605 --> @fissie commented on GitHub (Feb 1, 2021): Looks good now, thanks!
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#2459
No description provided.