It seems to me as if
The issue: I am running a program on the host, which has some sockets open.
The program loads a python plugin.
This python plugin then runs a shell via system(). The shell does
The problem: I cannot restart the main program while that daemon in the jail is still running, because the sockets of the main program do not O_CLOEXEC, and they are happily inherited all the way through.
I also cannot add that O_CLOEXEC, because then likely other things will break.
Then I considered that it is anyway a rather bad idea to hand all these file descriptors over to somebody in a jail, so they should be closed already on the host side, and not only later in the jailed daemon process.
So I tried to do it the usual way, forking the process, closing the descriptors in the child, and only then running the desired system().
But that does apparently not work in a python plugin:
Fatal Python error: _PyInterpreterState_DeleteExceptMain: not main interpreter
(see also https://github.com/python/cpython/issues/87680)
Then I figured (i.e. googled) that I might also close the descriptors from shell - but it seems our normal shell cannot do it; it fails for descriptors from 10 up. When I install
sh
would only accept a maximum of 9. Is that true?The issue: I am running a program on the host, which has some sockets open.
The program loads a python plugin.
This python plugin then runs a shell via system(). The shell does
jexec
, then su somebody
, then start another program in that jail, and that program does daemonize.The problem: I cannot restart the main program while that daemon in the jail is still running, because the sockets of the main program do not O_CLOEXEC, and they are happily inherited all the way through.
I also cannot add that O_CLOEXEC, because then likely other things will break.
Then I considered that it is anyway a rather bad idea to hand all these file descriptors over to somebody in a jail, so they should be closed already on the host side, and not only later in the jailed daemon process.
So I tried to do it the usual way, forking the process, closing the descriptors in the child, and only then running the desired system().
But that does apparently not work in a python plugin:
Fatal Python error: _PyInterpreterState_DeleteExceptMain: not main interpreter
(see also https://github.com/python/cpython/issues/87680)
Then I figured (i.e. googled) that I might also close the descriptors from shell - but it seems our normal shell cannot do it; it fails for descriptors from 10 up. When I install
bash
, that can apparently do it:
Code:
cmd = ("/usr/local/bin/bash -c 'n=`/usr/bin/ulimit -Hn`;" +
"for i in `/usr/bin/seq -f %.0f 3 $n`; do " +
"eval \"exec $i>&-\"; done;" + cmd + "'")