summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-10-10 03:19:39 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-10-10 03:19:39 (GMT)
commitf86d63e4f04f368450f5a4e9dd3dd6c282c43bf1 (patch)
treed7311c0b8dc8a95722b618c6dd07a1325aca1fa4
parent0407aeae01e38098a8dfa6fec4a04d254f8b6517 (diff)
downloadcpython-f86d63e4f04f368450f5a4e9dd3dd6c282c43bf1.zip
cpython-f86d63e4f04f368450f5a4e9dd3dd6c282c43bf1.tar.gz
cpython-f86d63e4f04f368450f5a4e9dd3dd6c282c43bf1.tar.bz2
Fix two memory leaks in socket.ssl().
XXX [1] These changes aren't tested very thoroughly, because regrtest doesn't do any SSL tests. I've done some trivial tests on my own, but don't really know how to use the key and cert files. In one case, an SSL-level error causes Python to dump core. I'll get the fixed in the next round of changes. XXX [2] The checkin removes the x_attr member of the SSLObject struct. I'm not sure if this is kosher for backwards compatibility at the binary level. Perhaps its safer to keep the member but keep it assigned to NULL. And the leaks? newSSLObject() called PyDict_New(), stored the result in x_attr without checking it, and later stored NULL in x_attr without doing anything to the dict. So the dict always leaks. There is no further reference to x_attr, so I just removed it completely. The error cases in newSSLObject() passed the return value of PyString_FromString() directly to PyErr_SetObject(). PyErr_SetObject() expects a borrowed reference, so the string leaked.
-rw-r--r--Modules/socketmodule.c68
1 files changed, 29 insertions, 39 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index 4ddaf9c..8db6aeb 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -491,7 +491,6 @@ typedef struct {
typedef struct {
PyObject_HEAD
PySocketSockObject *Socket; /* Socket on which we're layered */
- PyObject *x_attr; /* Attributes dictionary */
SSL_CTX* ctx;
SSL* ssl;
X509* server_cert;
@@ -2499,54 +2498,41 @@ static SSLObject *
newSSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file)
{
SSLObject *self;
+ PyObject *error = NULL;
self = PyObject_New(SSLObject, &SSL_Type); /* Create new object */
if (self == NULL){
- PyErr_SetObject(SSLErrorObject,
- PyString_FromString("newSSLObject error"));
- return NULL;
+ error = PyString_FromString("newSSLObject error");
+ goto fail;
}
memset(self->server, '\0', sizeof(char) * 256);
memset(self->issuer, '\0', sizeof(char) * 256);
- self->x_attr = PyDict_New();
self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */
if (self->ctx == NULL) {
- PyErr_SetObject(SSLErrorObject,
- PyString_FromString("SSL_CTX_new error"));
- PyObject_Del(self);
- return NULL;
+ error = PyString_FromString("SSL_CTX_new error");
+ goto fail;
}
- if ( (key_file && !cert_file) || (!key_file && cert_file) )
- {
- PyErr_SetObject(SSLErrorObject,
- PyString_FromString(
- "Both the key & certificate files must be specified"));
- PyObject_Del(self);
- return NULL;
+ if ((key_file && !cert_file) || (!key_file && cert_file)) {
+ error = PyString_FromString(
+ "Both the key & certificate files must be specified");
+ goto fail;
}
- if (key_file && cert_file)
- {
+ if (key_file && cert_file) {
if (SSL_CTX_use_PrivateKey_file(self->ctx, key_file,
- SSL_FILETYPE_PEM) < 1)
- {
- PyErr_SetObject(SSLErrorObject,
- PyString_FromString(
- "SSL_CTX_use_PrivateKey_file error"));
- PyObject_Del(self);
- return NULL;
+ SSL_FILETYPE_PEM) < 1) {
+ error = PyString_FromString(
+ "SSL_CTX_use_PrivateKey_file error");
+ goto fail;
}
if (SSL_CTX_use_certificate_chain_file(self->ctx,
- cert_file) < 1)
- {
- PyErr_SetObject(SSLErrorObject,
- PyString_FromString(
- "SSL_CTX_use_certificate_chain_file error"));
- PyObject_Del(self);
- return NULL;
+ cert_file) < 1) {
+ error = PyString_FromString(
+ "SSL_CTX_use_certificate_chain_file error");
+ goto fail;
}
}
@@ -2556,12 +2542,11 @@ newSSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file)
SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */
SSL_set_connect_state(self->ssl);
+ /* Actually negotiate SSL connection */
+ /* XXX If SSL_connect() returns 0, it's also a failure. */
if ((SSL_connect(self->ssl)) == -1) {
- /* Actually negotiate SSL connection */
- PyErr_SetObject(SSLErrorObject,
- PyString_FromString("SSL_connect error"));
- PyObject_Del(self);
- return NULL;
+ error = PyString_FromString("SSL_connect error");
+ goto fail;
}
self->ssl->debug = 1;
@@ -2571,10 +2556,16 @@ newSSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file)
X509_NAME_oneline(X509_get_issuer_name(self->server_cert),
self->issuer, 256);
}
- self->x_attr = NULL;
self->Socket = Sock;
Py_INCREF(self->Socket);
return self;
+ fail:
+ if (error) {
+ PyErr_SetObject(SSLErrorObject, error);
+ Py_DECREF(error);
+ }
+ Py_DECREF(self);
+ return NULL;
}
/* This is the Python function called for new object initialization */
@@ -2629,7 +2620,6 @@ static void SSL_dealloc(SSLObject *self)
X509_free (self->server_cert);
SSL_free(self->ssl);
SSL_CTX_free(self->ctx);
- Py_XDECREF(self->x_attr);
Py_XDECREF(self->Socket);
PyObject_Del(self);
}