netblue30 / firejail

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

Visual Studio Code nodejs extension fails to execute a command correctly #6015

Closed SjoerdV closed 9 months ago

SjoerdV commented 10 months ago

Description

When firejail is managing Visual Studio Code (code OR codium) sandbox firejail /usr/bin/codium . --no-sandbox --unity-launch The 'AsciiDoc' extension (NODEJS) fails to export an .adoc file to PDF. I imagine a lot of extensions execute external programs from within the vscode sandbox, so this might be a more generic issue.

Steps to Reproduce

  1. The 'AsciiDoc' extension (NODEJS) has a command 'Export document as PDF' which triggers /home/user/.vscode-oss/extensions/asciidoctor.asciidoctor-vscode-3.1.5/dist/src/commands/exportAsPDF.js
  2. This starts a program /usr/local/bin/asciidoctor-pdf symlinked to /var/lib/gems/2.7.0/gems/asciidoctor-pdf-2.3.9/bin/asciidoctor-pdf
  3. Which returns the error: /usr/lib/ruby/vendor_ruby/rubygems/core_ext/kernel_require.rb:85:in `require': /var/lib/gems/2.7.0/gems/date-3.3.3/lib/date_core.so: failed to map segment from shared object - /var/lib/gems/2.7.0/gems/date-3.3.3/lib/date_core.so (LoadError)

A lot of paths are involved but I noblacklisted them all. Also the executing of the .rb file needs an .so file loaded, this might complicate things

Expected behavior

The pdf file should be saved correctly

Actual behavior

eror occured (see above)

Behavior without a profile

_What changed calling LC_ALL=C firejail --noprofile /path/to/program in a terminal?_

Same error!

What changed calling /path/to/program in a terminal?

Error goes away and PDF is saved correctly

Additional context

AppArmor is disabled for the code or codium app, so that is not an issue.

I have tried a lot of code.local ignore statements, but it did not help

I tried --build to build my own profile, but it only added a bunch of whitelist statements that I don't want.

I tried syscalls.sh but my journal did not detect a single syscall

Environment

Checklist

Log

Output of LC_ALL=C firejail /path/to/program

``` Parent pid 156953, child pid 156954 Child process initialized in 3.58 ms ```

Output of LC_ALL=C firejail --debug /path/to/program

``` Building quoted command line: '/usr/bin/codium' './notebook.code-workspace' '--new-window' '--no-sandbox' '--unity-launch' Command name #codium# DISPLAY=:0 parsed as 0 Using the local network stack Parent pid 156115, child pid 156116 Initializing child process Host network configured PID namespace installed Mounting tmpfs on /run/firejail/mnt directory Creating empty /run/firejail/mnt/seccomp directory Creating empty /run/firejail/mnt/seccomp/seccomp.protocol file Creating empty /run/firejail/mnt/seccomp/seccomp.postexec file Creating empty /run/firejail/mnt/seccomp/seccomp.postexec32 file Mounting /proc filesystem representing the PID namespace Basic read-only filesystem: Mounting read-only /etc 863 812 259:5 /etc /etc ro,relatime master:1 - ext4 /dev/nvme0n1p5 rw,errors=remount-ro mountid=863 fsname=/etc dir=/etc fstype=ext4 Mounting noexec /etc 864 863 259:5 /etc /etc ro,nosuid,nodev,noexec,relatime master:1 - ext4 /dev/nvme0n1p5 rw,errors=remount-ro mountid=864 fsname=/etc dir=/etc fstype=ext4 Mounting read-only /var 865 812 259:5 /var /var ro,relatime master:1 - ext4 /dev/nvme0n1p5 rw,errors=remount-ro mountid=865 fsname=/var dir=/var fstype=ext4 Mounting noexec /var 866 865 259:5 /var /var ro,nosuid,nodev,noexec,relatime master:1 - ext4 /dev/nvme0n1p5 rw,errors=remount-ro mountid=866 fsname=/var dir=/var fstype=ext4 Mounting read-only /usr 867 812 259:5 /usr /usr ro,relatime master:1 - ext4 /dev/nvme0n1p5 rw,errors=remount-ro mountid=867 fsname=/usr dir=/usr fstype=ext4 Mounting tmpfs on /var/lock Mounting tmpfs on /var/tmp Mounting tmpfs on /var/log Mounting tmpfs on /var/lib/dhcp Mounting tmpfs on /var/lib/snmp Mounting tmpfs on /var/lib/sudo Create the new utmp file Mount the new utmp file Cleaning /home directory Cleaning /run/user directory Sanitizing /etc/passwd, UID_MIN 1000 Sanitizing /etc/group, GID_MIN 1000 Disable /home//.config/firejail Disable /run/firejail/sandbox Disable /run/firejail/network Disable /run/firejail/bandwidth Disable /run/firejail/name Disable /run/firejail/profile Disable /run/firejail/x11 blacklist /run/firejail/dbus Mounting read-only /proc/sys Remounting /sys directory Disable /sys/firmware Disable /sys/hypervisor Disable /sys/power Disable /sys/kernel/debug Disable /sys/kernel/vmcoreinfo Disable /proc/sys/fs/binfmt_misc Disable /proc/sys/kernel/core_pattern Disable /proc/sys/kernel/modprobe Disable /proc/sysrq-trigger Disable /proc/sys/vm/panic_on_oom Disable /proc/irq Disable /proc/bus Disable /proc/timer_list Disable /proc/kcore Disable /proc/kallsyms Disable /usr/lib/modules (requested /lib/modules) Disable /usr/lib/debug Disable /boot Disable /dev/port Disable /run/user/1000/gnupg Disable /run/user/1000/systemd Disable /dev/kmsg Disable /proc/kmsg Disable /sys/fs Disable /sys/module Current directory: /home//test DISPLAY=:0 parsed as 0 Mounting read-only /run/firejail/mnt/seccomp 1001 860 0:54 /seccomp /run/firejail/mnt/seccomp ro,nosuid - tmpfs tmpfs rw,mode=755,inode64 mountid=1001 fsname=/seccomp dir=/run/firejail/mnt/seccomp fstype=tmpfs Seccomp directory: ls /run/firejail/mnt/seccomp drwxr-xr-x root root 120 . drwxr-xr-x root root 160 .. -rw-r--r-- 632 seccomp -rw-r--r-- 432 seccomp.32 -rw-r--r-- 0 seccomp.postexec -rw-r--r-- 0 seccomp.postexec32 No active seccomp files Drop privileges: pid 1, uid 1000, gid 1000, force_nogroups 0 Closing non-standard file descriptors Starting application LD_PRELOAD=(null) execvp argument 0: /usr/bin/codium execvp argument 1: ./notebook.code-workspace execvp argument 2: --new-window execvp argument 3: --no-sandbox execvp argument 4: --unity-launch Child process initialized in 4.99 ms monitoring pid 2 Sandbox monitor: waitpid 2 retval 2 status 0 Sandbox monitor: monitoring 19 monitoring pid 19 ```

Output of firejail /path/to/program

``` Reading profile /etc/firejail/codium.profile Reading profile /etc/firejail/vscodium.profile Reading profile /etc/firejail/code.profile Reading profile /etc/firejail/allow-common-devel.inc Reading profile /etc/firejail/electron.profile Reading profile /etc/firejail/disable-common.inc Reading profile /etc/firejail/disable-programs.inc Warning: networking feature is disabled in Firejail configuration file Parent pid 158231, child pid 158232 Warning: NVIDIA card detected, nogroups command ignored Warning: cleaning all supplementary groups Child process initialized in 43.91 ms ```

glitsj16 commented 10 months ago

Thanks for your detailed reporting. The complexities involved here sure don't make it easy to come up with a quick one-liner fix. So please bare with me in the following.

What changed calling LC_ALL=C firejail --noprofile /path/to/program in a terminal? Same error!

I noticed that your debug log shows Mounting noexec /var, which might explain why the symlinked asciidoctor-pdf under /var/lib borks (steps 2 & 3 from your STR). When --noprofile also fails, that points me in the direction of troubles caused by a noexec somewhere down the line. Which IMO is also the reason why extra noblacklisting doesn't help in this context.

I'd try the below first (not exactly sure what nodejs might expect from the sandbox):

ignore noexec /tmp
ignore private-tmp

Also, instead of using --noprofile, try using noprofile.profile. The latter creates the weakest possible sandbox and is only another debug tool. If I'm at all having eyes on your issue I'd expect that to work due to the writable-var. Would be interesting if you could post output from

$ firejail --profile=noprofile.profile /path/to/program
SjoerdV commented 9 months ago

hi @glitsj16 thanks for your swift reply. The results are as follows:

1) adding

ignore noexec /tmp
ignore private-tmp

... has no effect

2)

Output of firejail --profile=noprofile.profile /path/to/program

``` Reading profile /etc/firejail/noprofile.profile Parent pid 168762, child pid 168763 Warning: cannot open source file /usr/lib/x86_64-linux-gnu/firejail/seccomp.debug32, file not copied Child process initialized in 79.90 ms ``` Now the extension works as expected indeed! But this is nearly the same as running without a sandbox, I guess.

What bugs me is that it seems there are no 'file not found' or 'can not execute' errors here, but a rather vague 'failed to map segment from shared object' error. Seems like something 'in memory' process is being blocked... Hope you have any more ideas ;-)

glitsj16 commented 9 months ago

Now the extension works as expected indeed! But this is nearly the same as running without a sandbox, I guess.

Correct. You'll need to integrate (some of the) noprofile.profile options into your code.local to keep a reasonably tight sandbox. My guess is the writable-var option probably will suffice, but some of the other ones might be needed too. Experiment and I'm pretty confident you'll have this working soon.

SjoerdV commented 9 months ago

Now the extension works as expected indeed! But this is nearly the same as running without a sandbox, I guess.

Correct. You'll need to integrate (some of the) noprofile.profile options into your code.local to keep a reasonably tight sandbox. My guess is the writable-var option probably will suffice, but some of the other ones might be needed too. Experiment and I'm pretty confident you'll have this working soon.

That's a great pointer, thanks! adding writable-var did the trick. Thanks again!

EDIT: my code.local file already had writable-run-user