
This issue trackerhas been migrated toGitHub, and is currentlyread-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.
Created on2016-08-16 04:53 bybenjamin.peterson, last changed2022-04-11 14:58 byadmin. This issue is nowclosed.
| Messages (2) | |||
|---|---|---|---|
| msg272829 -(view) | Author: Benjamin Peterson (benjamin.peterson)*![]() | Date: 2016-08-16 04:53 | |
Thomas E. Hybel reports:This vulnerability exists in the function newPySSLSocket in /Modules/_ssl.c. Theproblem is that Py_XDECREF is called on an object, self->server_hostname, whichisn't owned anymore.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,we call PyUnicode_Decode to initialize self->server_hostname = hostname. At thispoint both "self" and "self->server_hostname" have a reference count of 1.Later on we set self->Socket to be a new weakref. However if the call toPyWeakref_NewRef fails (the object cannot be weakly referenced) then we runPy_DECREF(self). Since the reference count of "self" drops to 0, PySSL_deallocis called, which runs this line: 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 isinappropriate both because "self" is now freed, and becauseself->server_hostname's refcount was already dropped in PySSL_dealloc.So this can be seen either as a use-after-free or as a double freevulnerability.Here's a reproducer:--- begin script ---import ssl, socket, _sockets = 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.pyStarting program: /home/xx/Python-3.5.2/python ./poc8.pyProgram received signal SIGSEGV, Segmentation fault.0x00007ffff67f7d9c in newPySSLSocket (sslctx=sslctx@entry=0x7ffff5ed15f8,sock=sock@entry=0x7ffff7e31dc0,socket_type=socket_type@entry=PY_SSL_SERVER, server_hostname=<optimized out>,inbio=inbio@entry=0x0,outbio=outbio@entry=0x0) at /home/xx/Python-3.5.2/Modules/_ssl.c:562562 Py_XDECREF(self->server_hostname);(gdb) p self->server_hostname$14 = (PyObject *) 0xdbdbdbdbdbdbdbdbI believe this should be fixed by simply removing the line"Py_XDECREF(self->server_hostname);"While fixing this, you might want to fix another issue in newPySSLSocket whichI'll describe next.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 callPy_DECREF(self). However the field self->server_hostname is an uninitializedvariable at this point! So the code in PySSL_dealloc which callsPy_XDECREF(self->server_hostname) could actually be working with an arbitrary,uninitialized pointer.Technically this is a separate vulnerability from the first, but I couldn't finda way to trigger it other than low-memory situations which aren't veryreliable.This could be fixed by initializing self->server_hostname to NULL before callingPy_DECREF(self). | |||
| msg272830 -(view) | Author: Roundup Robot (python-dev)![]() | Date: 2016-08-16 04:56 | |
New changeset98c86d5a6655 by Benjamin Peterson in branch '3.5':fix corner cases in the management of server_hostname (closes#27773)https://hg.python.org/cpython/rev/98c86d5a6655New changeseta8cd67e80ed3 by Benjamin Peterson in branch 'default':merge 3.5 (#27773)https://hg.python.org/cpython/rev/a8cd67e80ed3 | |||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:58:34 | admin | set | github: 71960 |
| 2021-11-04 14:21:14 | eryksun | set | messages: -msg405691 |
| 2021-11-04 14:21:03 | eryksun | set | nosy: -lys.nikolaou,pablogsal,ahmedsayeed1982 versions: + Python 3.6, - Python 3.11 |
| 2021-11-04 12:09:16 | ahmedsayeed1982 | set | versions: + Python 3.11, - Python 3.5, Python 3.6 nosy: +pablogsal,ahmedsayeed1982,lys.nikolaou, -benjamin.peterson,python-dev messages: +msg405691 components: + Parser |
| 2016-08-16 04:56:26 | python-dev | set | status: open -> closed nosy: +python-dev messages: +msg272830 resolution: fixed stage: resolved |
| 2016-08-16 04:53:37 | benjamin.peterson | create | |