Skip to content

cmdline: stop overwriting --exec_file with positional argv[0]#269

Merged
robertswiecki merged 1 commit into
google:masterfrom
philwo:fix/exec-file-clobbered-by-positional-argv
May 28, 2026
Merged

cmdline: stop overwriting --exec_file with positional argv[0]#269
robertswiecki merged 1 commit into
google:masterfrom
philwo:fix/exec-file-clobbered-by-positional-argv

Conversation

@philwo
Copy link
Copy Markdown
Member

@philwo philwo commented May 24, 2026

When I bumped my nsjail version to the latest master, my remote execution backend suddenly failed to execute actions with errors like this:

build step: rust_rlib "./local_rustc_sysroot/lib/rustlib/x86_64-unknown-linux-gnu/lib/libprofiler_builtins_profiler_builtins.rlib"
siso_rule: rust_rlib
stderr:
[E][2026-05-24T00:56:55+0000][1] newProc():257 execve('python3') failed: No such file or directory
[F][2026-05-24T00:56:55+0000][1] runChild():551 Launching child process failed
[W][2026-05-24T09:56:55+0900][466248] runChild():571 Received error message from the child process before it has been executed
[E][2026-05-24T09:56:55+0900][466248] standaloneMode():299 Couldn't launch the child process
build failed

I traced this back to commit 91e692a ("net: support for network rules"), which seems to have accidentally introduced a regression in the handling of the --exec_file flag. It is now silently ignored whenever positional args are also passed:

nsjail --exec_file /usr/bin/python3 -- python3 -c 'print("hi")'

... ends up calling execve("python3", …) instead of execve("/usr/bin/python3", …), which fails with ENOENT for me.

Removing the unconditional set_path added in that commit fixes it. The existing fallback below that code already handles the config-override case: if no -x was given, has_path() is false, and the fallback sets the path from the positional argv[0].

Repro

# Works with nsjail 3.6
❯ nsjail --chroot / --exec_file /usr/bin/echo -- echo hello
[I][2026-05-24T10:40:54+0900] Mode: STANDALONE_ONCE
[I][2026-05-24T10:40:54+0900] Jail parameters: hostname:'NSJAIL', chroot:'/', process:'/usr/bin/echo', bind:[::]:0, max_conns:0, max_conns_per_ip:0, time_limit:600, daemonize:false, clone_newnet:true, clone_newuser:true, clone_newns:true, clone_newpid:true, clone_newipc:true, clone_newuts:true, cgroupv2:false, keep_caps:false, disable_no_new_privs:false, max_cpus:0
[I][2026-05-24T10:40:54+0900] Mount: '/' -> '/' type:'' options:'' dir:true
[I][2026-05-24T10:40:54+0900] Mount: '/proc' type:'proc' options:'' dir:true
[I][2026-05-24T10:40:54+0900] Uid map: inside_uid:1000 outside_uid:1000 count:1 newuidmap:false
[I][2026-05-24T10:40:54+0900] Gid map: inside_gid:1000 outside_gid:1000 count:1 newgidmap:false
[I][2026-05-24T10:40:54+0900] Executing '/usr/bin/echo' for '[STANDALONE MODE]'
hello
[I][2026-05-24T10:40:54+0900] pid=595786 ([STANDALONE MODE]) exited with status: 0, (PIDs left: 0)

# Breaks with nsjail @ master (66ad78dc)
❯ nsjail --chroot / --exec_file /usr/bin/echo -- echo hello
[I][2026-05-24T10:42:31+0900] Mode: STANDALONE_ONCE
[I][2026-05-24T10:42:31+0900] Jail parameters: hostname:'NSJAIL', chroot:'/', process:'echo', bind:[::]:0, max_conns:0, max_conns_per_ip:0, time_limit:600, daemonize:false, clone_newnet:true, clone_newuser:true, clone_newns:true, clone_newpid:true, clone_newipc:true, clone_newuts:true, cgroupv2:false, keep_caps:false, disable_no_new_privs:false, max_cpus:0
[I][2026-05-24T10:42:31+0900] Mount: '/' -> '/' type:'' options:'' dir:true
[I][2026-05-24T10:42:31+0900] Mount: '/proc' type:'proc' options:'' dir:true
[I][2026-05-24T10:42:31+0900] Uid map: inside_uid:1000 outside_uid:1000 count:1 newuidmap:false
[I][2026-05-24T10:42:31+0900] Gid map: inside_gid:1000 outside_gid:1000 count:1 newgidmap:false
[I][2026-05-24T10:42:31+0900] Executing 'echo' for '[STANDALONE MODE]'
[E][2026-05-24T10:42:31+0900][1] newProc():257 execve('echo') failed: No such file or directory
[F][2026-05-24T10:42:31+0900][1] runChild():551 Launching child process failed
[W][2026-05-24T10:42:31+0900][475389] runChild():571 Received error message from the child process before it has been executed
[E][2026-05-24T10:42:31+0900][475389] standaloneMode():299 Couldn't launch the child process
[I][2026-05-24T10:42:31+0900] pid=475390 ([STANDALONE MODE]) exited with status: 255, (PIDs left: 0)

# Works again with this PR
❯ ./nsjail --chroot / --exec_file /usr/bin/echo -- echo hello
[I][2026-05-24T10:44:02+0900] Mode: STANDALONE_ONCE
[I][2026-05-24T10:44:02+0900] Jail parameters: hostname:'NSJAIL', chroot:'/', process:'/usr/bin/echo', bind:[::]:0, max_conns:0, max_conns_per_ip:0, time_limit:600, daemonize:false, clone_newnet:true, clone_newuser:true, clone_newns:true, clone_newpid:true, clone_newipc:true, clone_newuts:true, cgroupv2:false, keep_caps:false, disable_no_new_privs:false, max_cpus:0
[I][2026-05-24T10:44:02+0900] Mount: '/' -> '/' type:'' options:'' dir:true
[I][2026-05-24T10:44:02+0900] Mount: '/proc' type:'proc' options:'' dir:true
[I][2026-05-24T10:44:02+0900] Uid map: inside_uid:1000 outside_uid:1000 count:1 newuidmap:false
[I][2026-05-24T10:44:02+0900] Gid map: inside_gid:1000 outside_gid:1000 count:1 newgidmap:false
[I][2026-05-24T10:44:02+0900] Executing '/usr/bin/echo' for '[STANDALONE MODE]'
hello
[I][2026-05-24T10:44:02+0900] pid=597482 ([STANDALONE MODE]) exited with status: 0, (PIDs left: 0)

setupArgv() unconditionally called set_path(argv[optind]) when positional
arguments were present after --, clobbering any path previously set via
the -x / --exec_file flag. The intended behavior, documented in the help
text ("File to exec (default: argv[0])"), is for --exec_file to win and
fall back to argv[0] only when not given.

Remove the unconditional set_path; the existing fallback a few lines
below already sets the path from argv[0] when --exec_file was not
provided.
@philwo
Copy link
Copy Markdown
Member Author

philwo commented May 24, 2026

FYI @robertswiecki

@robertswiecki
Copy link
Copy Markdown
Collaborator

Thank you!

@robertswiecki robertswiecki merged commit 5674c62 into google:master May 28, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants