Issue 16945: rewrite CGIHTTPRequestHandler to always use subprocess (original) (raw)
On Unix, CGIHTTPRequestHandler.run_cgi() uses the following code to run a CGI script:
"""
pid = os.fork()
[...]
# Child
try:
try:
os.setuid(nobody)
except OSError:
pass
os.dup2(self.rfile.fileno(), 0)
os.dup2(self.wfile.fileno(), 1)
os.execve(scriptfile, args, env)
"""
It's basically reimplementing subprocess.Popen, with a potential securiy issue: open file descriptors are not closed before exec, which means that the CGI script - which is run as 'nobody' on Unix to reduce its priviledges - can inherit open sockets or files (unless they're close-on-exec)...
The attached patch rewrites run_cgi() to use subprocess on all platorms. I'm not at all familiar with CGI, so I don't guarantee it's correct, but the regression test test_httpservers passes on Linux.
It leads to cleaner and safer code, so if someone with some httpsever/CGI background could review it, it would be great.
The latest version of the patch passes on Linux, OpenIndiana and Windows.
Note that I did apply the select()-hack on all platforms (not only Windows), because if I understood #427345 correctly, it's really there to bypass a non-standard IE behavior (which appends trailing '\r\n'), and doesn't depend on the platform.