Movatterモバイル変換


[0]ホーム

URL:


homepage

Issue27773

This issue trackerhas been migrated toGitHub, and is currentlyread-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title:Excessive Py_XDECREF in the ssl module:
Type:crashStage:resolved
Components:ParserVersions:Python 3.6
process
Status:closedResolution:fixed
Dependencies:Superseder:
Assigned To:Nosy List:
Priority:normalKeywords:

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)*(Python committer)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)(Python triager)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
DateUserActionArgs
2022-04-11 14:58:34adminsetgithub: 71960
2021-11-04 14:21:14eryksunsetmessages: -msg405691
2021-11-04 14:21:03eryksunsetnosy: -lys.nikolaou,pablogsal,ahmedsayeed1982

versions: + Python 3.6, - Python 3.11
2021-11-04 12:09:16ahmedsayeed1982setversions: + 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:26python-devsetstatus: open -> closed

nosy: +python-dev
messages: +msg272830

resolution: fixed
stage: resolved
2016-08-16 04:53:37benjamin.petersoncreate
Supported byThe Python Software Foundation,
Powered byRoundup
Copyright © 1990-2022,Python Software Foundation
Legal Statements

[8]ページ先頭

©2009-2026 Movatter.jp