From b4c41481e2d5ef127199a4601417a6819053c3fd Mon Sep 17 00:00:00 2001 From: Roy Williams Date: Mon, 17 Oct 2016 11:33:20 -0700 Subject: [PATCH] Fix leak of duplicate file descriptor for bound sockets. `socket.fromfd` does not close the original file descriptor, so we have to explicitly close it to avoid a leak. See also: http://bugs.python.org/issue10099 --- gunicorn/sock.py | 5 ++++- tests/test_sock.py | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/gunicorn/sock.py b/gunicorn/sock.py index 9c73758a..6354fefe 100644 --- a/gunicorn/sock.py +++ b/gunicorn/sock.py @@ -25,10 +25,13 @@ class BaseSocket(object): self.cfg_addr = address if fd is None: sock = socket.socket(self.FAMILY, socket.SOCK_STREAM) + bound = False else: sock = socket.fromfd(fd, self.FAMILY, socket.SOCK_STREAM) + os.close(fd) + bound = True - self.sock = self.set_options(sock, bound=(fd is not None)) + self.sock = self.set_options(sock, bound=bound) def __str__(self, name): return "" % self.sock.fileno() diff --git a/tests/test_sock.py b/tests/test_sock.py index 1c514f08..11356c86 100644 --- a/tests/test_sock.py +++ b/tests/test_sock.py @@ -6,10 +6,13 @@ except ImportError: from gunicorn import sock +@mock.patch('os.close') @mock.patch('os.getpid') @mock.patch('os.unlink') @mock.patch('socket.fromfd') -def test_unix_socket_close_unlink(fromfd, unlink, getpid): - gsock = sock.UnixSocket('test.sock', mock.Mock(), mock.Mock(), mock.Mock()) +def test_unix_socket_close_unlink(fromfd, unlink, getpid, close): + fd = 42 + gsock = sock.UnixSocket('test.sock', mock.Mock(), mock.Mock(), fd=fd) gsock.close() unlink.assert_called_with("test.sock") + close.assert_called_with(fd)