google/nsjail

Should subprocNewProc() respect PATH?

rragliamzanov opened this issue · 5 comments

I prepared /chroot/ with selected binaries in /chroot/bin/

When I run nsjail --chroot /chroot/ -E PATH=/bin date I got error:

[I][2021-04-21T14:49:04+0000] Executing 'date' for '[STANDALONE MODE]'
[D][2021-04-21T14:49:04+0000][1] void subproc::subprocNewProc(nsjconf_t*, int, int, int, int, int)():184  Arg: 'date'
[E][2021-04-21T14:49:04+0000][1] void subproc::subprocNewProc(nsjconf_t*, int, int, int, int, int)():205 execve('date') failed: No such file or directory
[F][2021-04-21T14:49:04+0000][1] bool subproc::runChild(nsjconf_t*, int, int, int, int)():448 Launching child process failed
[W][2021-04-21T14:49:04+0000][12] bool subproc::runChild(nsjconf_t*, int, int, int, int)():478 Received error message from the child process before it has been executed
[E][2021-04-21T14:49:04+0000][12] int nsjail::standaloneMode(nsjconf_t*)():256 Couldn't launch the child process
[D][2021-04-21T14:49:04+0000][12] int main(int, char**)():343 Returning with 255

Code of the function looks like it sets environment variables with putenv, but execv is called, which doesn't respect PATH when calling binaries.

nsjail doesn't use PATH when executing commands, please try with /bin/date

It works will full path to the binary, but I have binaries in different directories and I need to call them by name only for this task.

nsjail doesn't use PATH when executing commands

There is a security reason for this or it is just unemplemented?

As far as I know only(?) shells use $PATH to execute files without full path for convenience reasons - you would not want to enter the full path on your shell the whole time.

Considering that nsjail is not a shell, I think it should not care about $PATH. Maybe you want to run a shell first and execute your command within that shell instead?

nsjail --chroot /chroot/ -E PATH=/bin /bin/sh -c 'date; id; echo Hi'

Yup, we want to be specific when creating processes from binaries, as this might affect security (executing something that shouldn't be launched, because there are copies lying around in e.g. /usr/local)

There's also execv() (as opposed to execve() or fexecve()) which uses PATH, and this could be used here, but this should be only used with shells or with system() from processes - in situations where such search heuristics will not cause unwanted side-effects.

As @fluxchief mentioned, feel free to run your commands via /bin/sh -c - just you need -- before /bin/sh because some getopt() magic, so

nsjail --chroot / -E PATH=/bin:/usr/bin -- /bin/sh -c 'date; id; echo Hi'

Patching execv() call to execvp() has worked but with having possible security leak in mind.

Thanks for option with runnning shell.