Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a9002f8

Browse files
committed
Fix SF #754870, SSL crash interpreter when remote side closes during connect
Also fix a memory leak.
1 parent b346096 commit a9002f8

2 files changed

Lines changed: 39 additions & 2 deletions

File tree

Lib/test/test_socket_ssl.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
from test import test_support
44
import socket
5+
import time
56

67
# Optionally test SSL support. This requires the 'network' resource as given
78
# on the regrtest command line.
89
skip_expected = not (test_support.is_resource_enabled('network') and
910
hasattr(socket, "ssl"))
1011

11-
def test_main():
12+
def test_basic():
1213
test_support.requires('network')
1314
if not hasattr(socket, "ssl"):
1415
raise test_support.TestSkipped("socket module has no ssl support")
@@ -28,5 +29,40 @@ def test_main():
2829
buf = f.read()
2930
f.close()
3031

32+
def test_rude_shutdown():
33+
try:
34+
import thread
35+
except ImportError:
36+
return
37+
38+
# some random port to connect to
39+
PORT = 9934
40+
def listener():
41+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
42+
s.bind(('', PORT))
43+
s.listen(5)
44+
s.accept()
45+
del s
46+
thread.exit()
47+
48+
def connector():
49+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
50+
s.connect(('', PORT))
51+
try:
52+
ssl_sock = socket.ssl(s)
53+
except socket.sslerror:
54+
pass
55+
else:
56+
raise test_support.TestFailed, \
57+
'connecting to closed SSL socket failed'
58+
59+
thread.start_new_thread(listener, ())
60+
time.sleep(1)
61+
connector()
62+
63+
def test_main():
64+
test_rude_shutdown()
65+
test_basic()
66+
3167
if __name__ == "__main__":
3268
test_main()

Modules/_ssl.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ PySSL_SetError(PySSLObject *obj, int ret)
110110
{
111111
unsigned long e = ERR_get_error();
112112
if (e == 0) {
113-
if (ret == 0) {
113+
if (ret == 0 || !obj->Socket) {
114114
p = PY_SSL_ERROR_EOF;
115115
errstr = "EOF occurred in violation of protocol";
116116
} else if (ret == -1) {
@@ -432,6 +432,7 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
432432
timedout = wait_for_timeout(self->Socket, 0);
433433
if (timedout) {
434434
PyErr_SetString(PySSLErrorObject, "The read operation timed out");
435+
Py_DECREF(buf);
435436
return NULL;
436437
}
437438
do {

0 commit comments

Comments
 (0)