Skip to content

Commit 9070cd5

Browse files
miss-islingtonscrievevstinner
authored
[3.15] gh-160561: Close the duplicated descriptor when socket.fromfd() fails (GH-160579) (#160785)
gh-160561: Close the duplicated descriptor when socket.fromfd() fails (GH-160579) (cherry picked from commit 6c695bf) Co-authored-by: scrieve <86650480+scrieve@users.noreply.github.com> Co-authored-by: wlkr73 <86650480+wlkr73@users.noreply.github.com> Co-authored-by: lumenyr <86650480+lumenyr@users.noreply.github.com> Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent e62d391 commit 9070cd5

3 files changed

Lines changed: 23 additions & 1 deletion

File tree

‎Lib/socket.py‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,11 @@ def fromfd(fd, family, type, proto=0):
561561
descriptor. The remaining arguments are the same as for socket().
562562
"""
563563
nfd = dup(fd)
564-
return socket(family, type, proto, nfd)
564+
try:
565+
return socket(family, type, proto, nfd)
566+
except:
567+
close(nfd)
568+
raise
565569

566570
if hasattr(_socket.socket, "sendmsg"):
567571
def send_fds(sock, buffers, fds, flags=0, address=None):

‎Lib/test/test_socket.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3175,6 +3175,23 @@ def testFromFd(self):
31753175
def _testFromFd(self):
31763176
self.serv_conn.send(MSG)
31773177

3178+
def testFromFdError(self):
3179+
# Make sure that the fromfd() duplicated socket is closed on error.
3180+
fd = self.cli_conn.fileno()
3181+
fd_count_before = os_helper.fd_count()
3182+
3183+
with self.assertRaises(TypeError):
3184+
socket.fromfd(fd, "not-a-valid-family", socket.SOCK_STREAM)
3185+
with self.assertRaises(TypeError):
3186+
socket.fromfd(fd, socket.AF_INET, "not-a-valid-type")
3187+
with self.assertRaises(OverflowError):
3188+
socket.fromfd(fd, socket.AF_INET, 1 << 100)
3189+
3190+
self.assertEqual(os_helper.fd_count(), fd_count_before)
3191+
3192+
def _testFromFdError(self):
3193+
pass
3194+
31783195
def testDup(self):
31793196
# Testing dup()
31803197
sock = self.cli_conn.dup()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix a descriptor leak in :func:`socket.fromfd` when the socket constructor rejects its arguments. The duplicated descriptor was never closed.

0 commit comments

Comments
 (0)