pymad/pymad — pull request #43 by coldfix (2014-03-17 23:52:38+00:00)
Title: Usage of multiprocessing causes handle leakage

When spawning a new process via `multiprocessing.Process` the child receives a copy of all handles in the parent process. This has problematic side effects for any communication protocol in the parent process that relies on closing handles at some point.
Furthermore, this is a security issue: suppose the parent process has obtained a handle to a secure resource (e.g. SSL socket) and somebody might succeed to use faulty MADX commands to access the handle (I'd say that is quite possible).

The following example demonstrates that it is not sufficient to close a handle in the parent process, since the child has a copy which it can still use:

```python
import multiprocessing

_global = []

def child(conn):
txt = conn.recv()
_global[0].write(txt)
_global[0].close()
conn.send(txt)

def parent():
_global.append(open('x.txt', 'w'))
lconn, rconn = multiprocessing.Pipe(True)
process = multiprocessing.Process(target=child, args=(rconn,))
process.start()
_global[0].close()
lconn.send('Hello World!')
lconn.recv()
print(open('x.txt').read()) # "Hello World!"

if __name__ == '__main__':
parent()
```

I have looked into solutions for this problem. I do not think there is any nice fix if sticking to `multiprocessing`. The `subprocess.Popen(..., close_fds=True)` command allows to close all inherited handles. The problem is, that this also closes any opened `Pipe` which makes it necessary to use another mechanism for IPC.

The next thing that comes to mind is using sockets. This creates the next issue: how to make sure that the connection is authenticated and secure against tempering? Possibly, SSL could be used, but this is even more additional complexity (worth?).

Please let me know if you have any suggestions for reliable/secure local IPC.