-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
Excessive Py_XDECREF in the ssl module: #71960
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thomas E. Hybel reports: This vulnerability exists in the function newPySSLSocket in /Modules/_ssl.c. The The code looks like this: static PySSLSocket *
newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock,
enum py_ssl_server_or_client socket_type,
char *server_hostname,
PySSLMemoryBIO *inbio, PySSLMemoryBIO *outbio)
{
PySSLSocket *self;
...
if (server_hostname != NULL) {
hostname = PyUnicode_Decode(server_hostname, strlen(server_hostname),
"idna", "strict");
...
self->server_hostname = hostname;
}
...
if (sock != NULL) {
self->Socket = PyWeakref_NewRef((PyObject *) sock, NULL);
if (self->Socket == NULL) {
Py_DECREF(self);
Py_XDECREF(self->server_hostname);
return NULL;
}
}
} We're initializing the "self" variable. If a hostname was given as an argument, Later on we set self->Socket to be a new weakref. However if the call to Py_XDECREF(self->server_hostname); Now self->server_hostname's refcount drops to 0 and it is freed. Then, back in newPySSLSocket, we run Py_XDECREF(self->server_hostname); which is So this can be seen either as a use-after-free or as a double free Here's a reproducer: --- begin script --- import ssl, socket, _socket
s = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
s.context._wrap_socket(_socket.socket(), server_side=1) --- end script --- On my machine (Python-3.5.2, 64-bits, --with-pydebug) it crashes: (gdb) r ./poc8.py Program received signal SIGSEGV, Segmentation fault. I believe this should be fixed by simply removing the line While fixing this, you might want to fix another issue in newPySSLSocket which The separate problem lies here: if (server_hostname != NULL) {
hostname = PyUnicode_Decode(server_hostname, strlen(server_hostname),
"idna", "strict");
if (hostname == NULL) {
Py_DECREF(self);
return NULL;
}
self->server_hostname = hostname;
} As we can see, PyUnicode_Decode is called. If PyUnicode_Decode fails, we call Technically this is a separate vulnerability from the first, but I couldn't find This could be fixed by initializing self->server_hostname to NULL before calling |
New changeset 98c86d5a6655 by Benjamin Peterson in branch '3.5': New changeset a8cd67e80ed3 by Benjamin Peterson in branch 'default': |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: