EtiennePerot / safe-code-execution

Code execution utilities for Open WebUI & Ollama
Apache License 2.0
172 stars 12 forks source link

Problem with hard way in docker #26

Open phpia opened 4 weeks ago

phpia commented 4 weeks ago

Description

Running inside docker this command echo 'print("Hello world!")' | python3 run_code.py

I get echo 'print("Hello world!")' | python3 run_code.py Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking for updates...', 'done': False}} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking for updates...', 'done': False}} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking messages for code blocks...', 'done': False}} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking messages for code blocks...', 'done': False}} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking if environment supports sandboxing...', 'done': False}} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking if environment supports sandboxing...', 'done': False}} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Initializing sandbox configuration...', 'done': False}} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Initializing sandbox configuration...', 'done': False}} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Running Python code in gVisor sandbox...', 'done': False}} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Running Python code in gVisor sandbox...', 'done': False}} Event: {'type': 'status', 'data': {'status': 'error', 'description': 'Sandbox exception: OSError: OSError in write_uid_map (#1): [Errno 1] Operation not permitted (other attempts: OSError in write_uid_map (#2): [Errno 1] Operation not permitted; OSError in write_uid_map (#3): [Errno 1] Operation not permitted); unshare_user (euid=0 egid=0 pid=166 do_resource_limiting=True initial_cgroup_name=None codeeval_cgroup_name=None controllers=None)', 'done': True}} {"status": "SANDBOX_ERROR", "output": "Sandbox exception: OSError: OSError in write_uid_map (#1): [Errno 1] Operation not permitted (other attempts: OSError in write_uid_map (#2): [Errno 1] Operation not permitted; OSError in write_uid_map (#3): [Errno 1] Operation not permitted); unshare_user (euid=0 egid=0 pid=166 do_resource_limiting=True initial_cgroup_name=None codeeval_cgroup_name=None controllers=None)"}

General information

Debug logs

Additional context

Thanks!

EtiennePerot commented 4 weeks ago

Can you turn on debug mode and provide full logs?

(Also, I see you're using a custom seccomp profile; is it the one from Dangerzone?)

phpia commented 4 weeks ago

Hi!, yes seccomp is from Dangerzone chat-export-1728031201796.json

Thanks!

EtiennePerot commented 3 weeks ago

Thanks. Sadly I didn't really add enough debug information to the function (only the tool) when running in debug mode, whoops.

In 46aa572e844f0d2a29e7acc7b4657a320ef99152 I have submitted a patch that adds this debug information. Please re-run it. This just adds debug information so I don't expect it to fix the problem, just to provide more complete logs.

Looking at the Linux documentation for user_namespaces(7), this could be due to the lack of CAP_SETFCAP. So here are some things to try:

phpia commented 3 weeks ago

Hi @EtiennePerot , first thanks for you time. Running command inside the docker containet I get the next error: root@e5fdfecb16f9:/app# unshare --map-root-user cat /proc/self/status unshare: write failed /proc/self/uid_map: Operation not permitted

chat-export-1728313256649.json

EtiennePerot commented 3 weeks ago

Thanks, this at least isolates the issue. Can you run the other commands in the docker container, without unshare --map-root-user?

phpia commented 3 weeks ago

Hi, I was running docker without this command :)

a-rbts commented 3 weeks ago

Hello, I am encountering a similar error message when hitting the button to run code after having set up the function, I suspect this is how OP started to look at the issue too.

Sandbox exception: OSError: write_uid_map (#1): [Errno 1] Operation not permitted (other attempts: write_uid_map (#2): [Errno 1] Operation not permitted; write_uid_map (#3): [Errno 1] Operation not permitted); unshare_user (euid=0 egid=0 pid=293 do_resource_limiting=True initial_cgroup_name=None codeeval_cgroup_name=None controllers=None) Name=python Umask=0022 State=R (running) Uid=65534 65534 65534 65534 Gid=65534 65534 65534 65534 Groups=65534 NStgid=293 NSpid=293 NSpgid=1 CapInh=0000000000000000 CapPrm=000001ffffffffff CapEff=000001ffffffffff CapBnd=000001ffffffffff CapAmb=0000000000000000 NoNewPrivs=0 Seccomp=0 Seccomp_filters=0

Based on the previous conversations I have tried the same steps, and ended up with the same issues as OP.

Getting to the last step, I have added the option --cap-add=SETFCAP to docker run and tried the different calls. Here are the results in order:

root@3918feaaeffd:/app/backend# python3 run_code.py --use_sample_code --debug Emitting status event: {'status': 'in_progress', 'description': 'Checking for updates...', 'done': False} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking for updates...', 'done': False}} Emitting status event: {'status': 'in_progress', 'description': 'Checking for updates...', 'done': False} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking for updates...', 'done': False}} Emitting status event: {'status': 'in_progress', 'description': 'Checking messages for code blocks...', 'done': False} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking messages for code blocks...', 'done': False}} Emitting status event: {'status': 'in_progress', 'description': 'Checking messages for code blocks...', 'done': False} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking messages for code blocks...', 'done': False}} Emitting status event: {'status': 'in_progress', 'description': 'Checking if environment supports sandboxing...', 'done': False} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking if environment supports sandboxing...', 'done': False}} Emitting status event: {'status': 'in_progress', 'description': 'Checking if environment supports sandboxing...', 'done': False} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Checking if environment supports sandboxing...', 'done': False}} Emitting status event: {'status': 'in_progress', 'description': 'Initializing sandbox configuration...', 'done': False} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Initializing sandbox configuration...', 'done': False}} Emitting status event: {'status': 'in_progress', 'description': 'Initializing sandbox configuration...', 'done': False} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Initializing sandbox configuration...', 'done': False}} Emitting status event: {'status': 'in_progress', 'description': 'Running Python code in gVisor sandbox...', 'done': False} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Running Python code in gVisor sandbox...', 'done': False}} Emitting status event: {'status': 'in_progress', 'description': 'Running Python code in gVisor sandbox...', 'done': False} Event: {'type': 'status', 'data': {'status': 'in_progress', 'description': 'Running Python code in gVisor sandbox...', 'done': False}} Emitting status event: {'status': 'error', 'description': '[DEBUG MODE] Sandbox exception: OSError: write_uid_map (#1): [Errno 1] Operation not permitted (other attempts: write_uid_map (#2): [Errno 1] Operation not permitted; write_uid_map (#3): [Errno 1] Operation not permitted); unshare_user (euid=0 egid=0 pid=513 do_resource_limiting=True initial_cgroup_name=None codeeval_cgroup_name=None controllers=None) Name=python3 Umask=0022 State=R (running) Uid=65534\t65534\t65534\t65534 Gid=65534\t65534\t65534\t65534 Groups=65534 NStgid=513 NSpid=513 NSpgid=511 CapInh=0000000000000000 CapPrm=000001ffffffffff CapEff=000001ffffffffff CapBnd=000001ffffffffff CapAmb=0000000000000000 NoNewPrivs=0 Seccomp=0 Seccomp_filters=0; body={\'messages\': [{\'role\': \'assistant\', \'content\': "python\\nprint(\'Hello from the sandbox!\')\\nimport datetime, sys\\nprint(\'Current date and time:\', datetime.datetime.now())\\nsys.stdout.flush()\\nimport shutil, subprocess\\nsubprocess.run([shutil.which(\'dmesg\')], check=True)\\nprint(\'Bye from the sandbox!\')\\n\\n\n"}]}; valves=[NETWORKING_ALLOWED=True MAX_RUNTIME_SECONDS=30 MAX_RAM_MEGABYTES=128 AUTO_INSTALL=True CHECK_FOR_UPDATES=True DEBUG=True MAX_FILES_PER_EXECUTION=32 MAX_FILES_PER_USER=4096 MAX_MEGABYTES_PER_USER=256 REQUIRE_RESOURCE_LIMITING=True WEB_ACCESSIBLE_DIRECTORY_PATH=\'$DATA_DIR/cache/functions/run_code\' WEB_ACCESSIBLE_DIRECTORY_URL=\'/cache/functions/run_code\']', 'done': True} Event: {'type': 'status', 'data': {'status': 'error', 'description': '[DEBUG MODE] Sandbox exception: OSError: write_uid_map (#1): [Errno 1] Operation not permitted (other attempts: write_uid_map (#2): [Errno 1] Operation not permitted; write_uid_map (#3): [Errno 1] Operation not permitted); unshare_user (euid=0 egid=0 pid=513 do_resource_limiting=True initial_cgroup_name=None codeeval_cgroup_name=None controllers=None) Name=python3 Umask=0022 State=R (running) Uid=65534\t65534\t65534\t65534 Gid=65534\t65534\t65534\t65534 Groups=65534 NStgid=513 NSpid=513 NSpgid=511 CapInh=0000000000000000 CapPrm=000001ffffffffff CapEff=000001ffffffffff CapBnd=000001ffffffffff CapAmb=0000000000000000 NoNewPrivs=0 Seccomp=0 Seccomp_filters=0; body={\'messages\': [{\'role\': \'assistant\', \'content\': "python\\nprint(\'Hello from the sandbox!\')\\nimport datetime, sys\\nprint(\'Current date and time:\', datetime.datetime.now())\\nsys.stdout.flush()\\nimport shutil, subprocess\\nsubprocess.run([shutil.which(\'dmesg\')], check=True)\\nprint(\'Bye from the sandbox!\')\\n\\n\n"}]}; valves=[NETWORKING_ALLOWED=True MAX_RUNTIME_SECONDS=30 MAX_RAM_MEGABYTES=128 AUTO_INSTALL=True CHECK_FOR_UPDATES=True DEBUG=True MAX_FILES_PER_EXECUTION=32 MAX_FILES_PER_USER=4096 MAX_MEGABYTES_PER_USER=256 REQUIRE_RESOURCE_LIMITING=True WEB_ACCESSIBLE_DIRECTORY_PATH=\'$DATA_DIR/cache/functions/run_code\' WEB_ACCESSIBLE_DIRECTORY_URL=\'/cache/functions/run_code\']', 'done': True}} {"status": "SANDBOX_ERROR", "output": "Sandbox exception: OSError: write_uid_map (#1): [Errno 1] Operation not permitted (other attempts: write_uid_map (#2): [Errno 1] Operation not permitted; write_uid_map (#3): [Errno 1] Operation not permitted); unshare_user (euid=0 egid=0 pid=513 do_resource_limiting=True initial_cgroup_name=None codeeval_cgroup_name=None controllers=None) Name=python3 Umask=0022 State=R (running) Uid=65534\t65534\t65534\t65534 Gid=65534\t65534\t65534\t65534 Groups=65534 NStgid=513 NSpid=513 NSpgid=511 CapInh=0000000000000000 CapPrm=000001ffffffffff CapEff=000001ffffffffff CapBnd=000001ffffffffff CapAmb=0000000000000000 NoNewPrivs=0 Seccomp=0 Seccomp_filters=0"}

root@3918feaaeffd:/app/backend# cat /proc/self/status Name: cat Umask: 0022 State: R (running) Tgid: 52 Ngid: 0 Pid: 52 PPid: 18 TracerPid: 0 Uid: 0 0 0 0 Gid: 0 0 0 0 FDSize: 256 Groups: 0 NStgid: 52 NSpid: 52 NSpgid: 52 NSsid: 18 Kthread: 0 VmPeak: 2792 kB VmSize: 2792 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 1408 kB VmRSS: 1408 kB RssAnon: 0 kB RssFile: 1408 kB RssShmem: 0 kB VmData: 356 kB VmStk: 132 kB VmExe: 36 kB VmLib: 1728 kB VmPTE: 40 kB VmSwap: 0 kB HugetlbPages: 0 kB CoreDumping: 0 THP_enabled: 1 untag_mask: 0xffffffffffffff Threads: 1 SigQ: 1/7662 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000000000 SigIgn: 0000000000000000 SigCgt: 0000000000000000 CapInh: 0000000000000000 CapPrm: 00000000a80425fb CapEff: 00000000a80425fb CapBnd: 00000000a80425fb CapAmb: 0000000000000000 NoNewPrivs: 0 Seccomp: 0 Seccomp_filters: 0 Speculation_Store_Bypass: vulnerable SpeculationIndirectBranch: unknown Cpus_allowed: 3 Cpus_allowed_list: 0-1 Mems_allowed: 00000000,00000001 Mems_allowed_list: 0 voluntary_ctxt_switches: 0 nonvoluntary_ctxt_switches: 2

root@3918feaaeffd:/app/backend# apt-get update && apt-get install -y libcap2-bin && capsh --print Get:1 http://deb.debian.org/debian bookworm InRelease [151 kB] Get:2 http://deb.debian.org/debian bookworm-updates InRelease [55.4 kB] Get:3 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB] Get:4 http://deb.debian.org/debian bookworm/main arm64 Packages [8689 kB] Get:5 http://deb.debian.org/debian bookworm-updates/main arm64 Packages [2468 B] Get:6 http://deb.debian.org/debian-security bookworm-security/main arm64 Packages [185 kB] Fetched 9131 kB in 3s (3626 kB/s) Reading package lists... Done Reading package lists... Done Building dependency tree... Done Reading state information... Done The following additional packages will be installed: libpam-cap The following NEW packages will be installed: libcap2-bin libpam-cap 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 48.4 kB of archives. After this operation, 417 kB of additional disk space will be used. Get:1 http://deb.debian.org/debian bookworm/main arm64 libcap2-bin arm64 1:2.66-4 [33.9 kB] Get:2 http://deb.debian.org/debian bookworm/main arm64 libpam-cap arm64 1:2.66-4 [14.5 kB] Fetched 48.4 kB in 0s (202 kB/s) debconf: delaying package configuration, since apt-utils is not installed Selecting previously unselected package libcap2-bin. (Reading database ... 17989 files and directories currently installed.) Preparing to unpack .../libcap2-bin_1%3a2.66-4_arm64.deb ... Unpacking libcap2-bin (1:2.66-4) ... Selecting previously unselected package libpam-cap:arm64. Preparing to unpack .../libpam-cap_1%3a2.66-4_arm64.deb ... Unpacking libpam-cap:arm64 (1:2.66-4) ... Setting up libcap2-bin (1:2.66-4) ... Setting up libpam-cap:arm64 (1:2.66-4) ... debconf: unable to initialize frontend: Dialog debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 78.) debconf: falling back to frontend: Readline Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap=ep Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chroot,cap_mknod,cap_audit_write,cap_setfcap Ambient set = Current IAB: !cap_dac_read_search,!cap_linux_immutable,!cap_net_broadcast,!cap_net_admin,!cap_ipc_lock,!cap_ipc_owner,!cap_sys_module,!cap_sys_rawio,!cap_sys_ptrace,!cap_sys_pacct,!cap_sys_admin,!cap_sys_boot,!cap_sys_nice,!cap_sys_resource,!cap_sys_time,!cap_sys_tty_config,!cap_lease,!cap_audit_control,!cap_mac_override,!cap_mac_admin,!cap_syslog,!cap_wake_alarm,!cap_block_suspend,!cap_audit_read,!cap_perfmon,!cap_bpf,!cap_checkpoint_restore Securebits: 00/0x0/1'b0 (no-new-privs=0) secure-noroot: no (unlocked) secure-no-suid-fixup: no (unlocked) secure-keep-caps: no (unlocked) secure-no-ambient-raise: no (unlocked) uid=0(root) euid=0(root) gid=0(root) groups=0(root) Guessed mode: HYBRID (4)

root@3918feaaeffd:/app/backend# unshare --map-root-user cat /proc/self/status unshare: write failed /proc/self/uid_map: Operation not permitted

So adding --cap-add=SETFCAP doesn't seem to make any difference.