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

Skip to content

Commit 94fbaac

Browse files
committed
Merged revisions 82204 via svnmerge from
svn+ssh://[email protected]/python/branches/py3k ........ r82204 | antoine.pitrou | 2010-06-25 00:34:04 +0200 (ven., 25 juin 2010) | 5 lines Issue #8682: The ssl module now temporary increments the reference count of a socket object got through `PyWeakref_GetObject`, so as to avoid possible deallocation while the object is still being used. ........
1 parent 53ec7d5 commit 94fbaac

2 files changed

Lines changed: 57 additions & 27 deletions

File tree

Misc/NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ C-API
7272
Library
7373
-------
7474

75+
- Issue #8682: The ssl module now temporary increments the reference count of
76+
a socket object got through ``PyWeakref_GetObject``, so as to avoid possible
77+
deallocation while the object is still being used.
78+
7579
- Issue #1368368: FancyURLOpener class changed to throw an Exception on wrong
7680
password instead of presenting an interactive prompt. Older behavior can be
7781
obtained by passing retry=True to http_error_xxx methods of FancyURLOpener.

Modules/_ssl.c

Lines changed: 53 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,11 @@ PySSL_SetError(PySSLObject *obj, int ret, char *filename, int lineno)
199199
errstr = "EOF occurred in violation of protocol";
200200
} else if (ret == -1) {
201201
/* underlying BIO reported an I/O error */
202+
Py_INCREF(s);
202203
ERR_clear_error();
203-
return s->errorhandler();
204+
v = s->errorhandler();
205+
Py_DECREF(s);
206+
return v;
204207
} else { /* possible? */
205208
p = PY_SSL_ERROR_SYSCALL;
206209
errstr = "Some I/O error occurred";
@@ -454,6 +457,7 @@ static PyObject *PySSL_SSLdo_handshake(PySSLObject *self)
454457
PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
455458
return NULL;
456459
}
460+
Py_INCREF(sock);
457461

458462
/* just in case the blocking state of the socket has been changed */
459463
nonblocking = (sock->sock_timeout >= 0.0);
@@ -468,9 +472,8 @@ static PyObject *PySSL_SSLdo_handshake(PySSLObject *self)
468472
ret = SSL_do_handshake(self->ssl);
469473
err = SSL_get_error(self->ssl, ret);
470474
PySSL_END_ALLOW_THREADS
471-
if(PyErr_CheckSignals()) {
472-
return NULL;
473-
}
475+
if (PyErr_CheckSignals())
476+
goto error;
474477
if (err == SSL_ERROR_WANT_READ) {
475478
sockstate = check_socket_and_wait_for_timeout(sock, 0);
476479
} else if (err == SSL_ERROR_WANT_WRITE) {
@@ -481,19 +484,20 @@ static PyObject *PySSL_SSLdo_handshake(PySSLObject *self)
481484
if (sockstate == SOCKET_HAS_TIMED_OUT) {
482485
PyErr_SetString(PySSLErrorObject,
483486
ERRSTR("The handshake operation timed out"));
484-
return NULL;
487+
goto error;
485488
} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
486489
PyErr_SetString(PySSLErrorObject,
487490
ERRSTR("Underlying socket has been closed."));
488-
return NULL;
491+
goto error;
489492
} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
490493
PyErr_SetString(PySSLErrorObject,
491494
ERRSTR("Underlying socket too large for select()."));
492-
return NULL;
495+
goto error;
493496
} else if (sockstate == SOCKET_IS_NONBLOCKING) {
494497
break;
495498
}
496499
} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
500+
Py_DECREF(sock);
497501
if (ret < 1)
498502
return PySSL_SetError(self, ret, __FILE__, __LINE__);
499503
self->ssl->debug = 1;
@@ -506,6 +510,10 @@ static PyObject *PySSL_SSLdo_handshake(PySSLObject *self)
506510

507511
Py_INCREF(Py_None);
508512
return Py_None;
513+
514+
error:
515+
Py_DECREF(sock);
516+
return NULL;
509517
}
510518

511519
static PyObject *
@@ -1175,9 +1183,12 @@ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
11751183
PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
11761184
return NULL;
11771185
}
1186+
Py_INCREF(sock);
11781187

1179-
if (!PyArg_ParseTuple(args, "y#:write", &data, &count))
1188+
if (!PyArg_ParseTuple(args, "y#:write", &data, &count)) {
1189+
Py_DECREF(sock);
11801190
return NULL;
1191+
}
11811192

11821193
/* just in case the blocking state of the socket has been changed */
11831194
nonblocking = (sock->sock_timeout >= 0.0);
@@ -1188,25 +1199,24 @@ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
11881199
if (sockstate == SOCKET_HAS_TIMED_OUT) {
11891200
PyErr_SetString(PySSLErrorObject,
11901201
"The write operation timed out");
1191-
return NULL;
1202+
goto error;
11921203
} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
11931204
PyErr_SetString(PySSLErrorObject,
11941205
"Underlying socket has been closed.");
1195-
return NULL;
1206+
goto error;
11961207
} else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
11971208
PyErr_SetString(PySSLErrorObject,
11981209
"Underlying socket too large for select().");
1199-
return NULL;
1210+
goto error;
12001211
}
12011212
do {
12021213
err = 0;
12031214
PySSL_BEGIN_ALLOW_THREADS
12041215
len = SSL_write(self->ssl, data, count);
12051216
err = SSL_get_error(self->ssl, len);
12061217
PySSL_END_ALLOW_THREADS
1207-
if(PyErr_CheckSignals()) {
1208-
return NULL;
1209-
}
1218+
if (PyErr_CheckSignals())
1219+
goto error;
12101220
if (err == SSL_ERROR_WANT_READ) {
12111221
sockstate = check_socket_and_wait_for_timeout(sock, 0);
12121222
} else if (err == SSL_ERROR_WANT_WRITE) {
@@ -1217,19 +1227,25 @@ static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
12171227
if (sockstate == SOCKET_HAS_TIMED_OUT) {
12181228
PyErr_SetString(PySSLErrorObject,
12191229
"The write operation timed out");
1220-
return NULL;
1230+
goto error;
12211231
} else if (sockstate == SOCKET_HAS_BEEN_CLOSED) {
12221232
PyErr_SetString(PySSLErrorObject,
12231233
"Underlying socket has been closed.");
1224-
return NULL;
1234+
goto error;
12251235
} else if (sockstate == SOCKET_IS_NONBLOCKING) {
12261236
break;
12271237
}
12281238
} while (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE);
1239+
1240+
Py_DECREF(sock);
12291241
if (len > 0)
12301242
return PyLong_FromLong(len);
12311243
else
12321244
return PySSL_SetError(self, len, __FILE__, __LINE__);
1245+
1246+
error:
1247+
Py_DECREF(sock);
1248+
return NULL;
12331249
}
12341250

12351251
PyDoc_STRVAR(PySSL_SSLwrite_doc,
@@ -1277,21 +1293,23 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
12771293
PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
12781294
return NULL;
12791295
}
1296+
Py_INCREF(sock);
12801297

12811298
if (!PyArg_ParseTuple(args, "|Oi:read", &dest, &count))
1282-
return NULL;
1299+
goto error;
1300+
12831301
if ((dest == NULL) || (dest == Py_None)) {
12841302
if (!(dest = PyByteArray_FromStringAndSize((char *) 0, len)))
1285-
return NULL;
1303+
goto error;
12861304
mem = PyByteArray_AS_STRING(dest);
12871305
} else if (PyLong_Check(dest)) {
12881306
len = PyLong_AS_LONG(dest);
12891307
if (!(dest = PyByteArray_FromStringAndSize((char *) 0, len)))
1290-
return NULL;
1308+
goto error;
12911309
mem = PyByteArray_AS_STRING(dest);
12921310
} else {
12931311
if (PyObject_GetBuffer(dest, &buf, PyBUF_CONTIG) < 0)
1294-
return NULL;
1312+
goto error;
12951313
mem = buf.buf;
12961314
len = buf.len;
12971315
if ((count > 0) && (count <= len))
@@ -1358,6 +1376,7 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
13581376
goto error;
13591377
}
13601378
done:
1379+
Py_DECREF(sock);
13611380
if (!buf_passed) {
13621381
PyObject *res = PyBytes_FromStringAndSize(mem, count);
13631382
Py_DECREF(dest);
@@ -1367,8 +1386,9 @@ static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
13671386
return PyLong_FromLong(count);
13681387
}
13691388
error:
1389+
Py_DECREF(sock);
13701390
if (!buf_passed) {
1371-
Py_DECREF(dest);
1391+
Py_XDECREF(dest);
13721392
} else {
13731393
PyBuffer_Release(&buf);
13741394
}
@@ -1393,6 +1413,7 @@ static PyObject *PySSL_SSLshutdown(PySSLObject *self)
13931413
PY_SSL_ERROR_NO_SOCKET, __FILE__, __LINE__);
13941414
return NULL;
13951415
}
1416+
Py_INCREF(sock);
13961417

13971418
/* Just in case the blocking state of the socket has been changed */
13981419
nonblocking = (sock->sock_timeout >= 0.0);
@@ -1442,24 +1463,29 @@ static PyObject *PySSL_SSLshutdown(PySSLObject *self)
14421463
else
14431464
PyErr_SetString(PySSLErrorObject,
14441465
"The write operation timed out");
1445-
return NULL;
1466+
goto error;
14461467
}
14471468
else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) {
14481469
PyErr_SetString(PySSLErrorObject,
14491470
"Underlying socket too large for select().");
1450-
return NULL;
1471+
goto error;
14511472
}
14521473
else if (sockstate != SOCKET_OPERATION_OK)
14531474
/* Retain the SSL error code */
14541475
break;
14551476
}
14561477

1457-
if (err < 0)
1478+
if (err < 0) {
1479+
Py_DECREF(sock);
14581480
return PySSL_SetError(self, err, __FILE__, __LINE__);
1459-
else {
1460-
Py_INCREF(sock);
1461-
return (PyObject *) sock;
14621481
}
1482+
else
1483+
/* It's already INCREF'ed */
1484+
return (PyObject *) sock;
1485+
1486+
error:
1487+
Py_DECREF(sock);
1488+
return NULL;
14631489
}
14641490

14651491
PyDoc_STRVAR(PySSL_SSLshutdown_doc,

0 commit comments

Comments
 (0)