Movatterモバイル変換


[0]ホーム

URL:


homepage

Issue25945

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:Type confusion in partial_setstate and partial_call leads to memory corruption
Type:crashStage:resolved
Components:Extension ModulesVersions:Python 3.6, Python 3.5, Python 2.7
process
Status:closedResolution:fixed
Dependencies:Superseder:
Assigned To: serhiy.storchakaNosy List: Ned Williamson, ncoghlan, python-dev, rhettinger, serhiy.storchaka
Priority:normalKeywords:patch

Created on2015-12-25 04:16 byNed Williamson, last changed2022-04-11 14:58 byadmin. This issue is nowclosed.

Files
File nameUploadedDescriptionEdit
partialpoc2.pyNed Williamson,2015-12-25 04:16
partial_setstate.patchserhiy.storchaka,2015-12-25 11:07review
Messages (6)
msg256976 -(view)Author: Ned Williamson (Ned Williamson)Date: 2015-12-25 04:16
static PyObject *partial_setstate(partialobject *pto, PyObject *state){    PyObject *fn, *fnargs, *kw, *dict;    if (!PyArg_ParseTuple(state, "OOOO",                          &fn, &fnargs, &kw, &dict))        return NULL;    Py_XDECREF(pto->fn);    Py_XDECREF(pto->args);    Py_XDECREF(pto->kw);    Py_XDECREF(pto->dict);    pto->fn = fn;    pto->args = fnargs; //we control pto->args here`partial_setstate` performs no checks on the objectsit is passed as an argument.static PyObject *partial_call(partialobject *pto, PyObject *args, PyObject *kw){    PyObject *ret;    PyObject *argappl = NULL, *kwappl = NULL;    assert (PyCallable_Check(pto->fn));    assert (PyTuple_Check(pto->args)); //assume pto->args is a tuple                                       //assertion not present in release build    assert (pto->kw == Py_None  ||  PyDict_Check(pto->kw));    if (PyTuple_GET_SIZE(pto->args) == 0) {        argappl = args;        Py_INCREF(args);    } else if (PyTuple_GET_SIZE(args) == 0) {        argappl = pto->args; //partial function called with no arguments        Py_INCREF(pto->args);    } else {        argappl = PySequence_Concat(pto->args, args);        if (argappl == NULL)            return NULL;    }    if (pto->kw == Py_None) {        kwappl = kw;        Py_XINCREF(kw);    } else {        kwappl = PyDict_Copy(pto->kw);        if (kwappl == NULL) {            Py_DECREF(argappl);            return NULL;        }        if (kw != NULL) {            if (PyDict_Merge(kwappl, kw, 1) != 0) {                Py_DECREF(argappl);                Py_DECREF(kwappl);                return NULL;            }        }    }    ret = PyObject_Call(pto->fn, argappl, kwappl); //pto->fn called with non-tuple argapplWe can see that in the provided POC there is an increment on a user-controlled address (in this case, the literal refcount of a given "argument" is interpreted as a pointer), as `_PyEval_EvalCodeWithName` does not validate the type of `PyObject **args` either (I assume this is a fair assumption for `_PyEval_EvalCodeWithName`, and the bug simply lies in the unsafe partial code.vagrant@vagrant-ubuntu-wily-64:/vagrant/Python-3.5.1$ gdb -q ./python.exe...(gdb) r partialpoc2.pyStarting program: /vagrant/Python-3.5.1/python.exe partialpoc2.py...Program received signal SIGSEGV, Segmentation fault._PyEval_EvalCodeWithName (_co=0x7ffff7045ae0, globals=<optimized out>,locals=locals@entry=0x0,args=args@entry=0x7ffff6fbc520, argcount=1280,kws=kws@entry=0x0, kwcount=0, defs=0x0, defcount=0,    kwdefs=0x0, closure=0x0, name=0x0, qualname=0x0) atPython/ceval.c:37933793            Py_INCREF(x);(gdb) i rrax            0x9b4b6810177384rbx            0x7ffff6fbc520140737337083168rcx            0x11rdx            0x22rsi            0x5001280rdi            0x00rbp            0x00x0rsp            0x7fffffffdb300x7fffffffdb30r8             0x5001280r9             0x00r10            0x7ffff74a6c58140737342237784r11            0x9b4b4010177344r12            0x00r13            0x00r14            0x7ffff6fb91e0140737337070048r15            0x7ffff7e1a048140737352147016rip            0x4fc7710x4fc771 <_PyEval_EvalCodeWithName+961>eflags         0x10202[ IF RF ]cs             0x3351ss             0x2b43ds             0x00es             0x00fs             0x00gs             0x00(gdb) x/3i $pc=> 0x4fc771 <_PyEval_EvalCodeWithName+961>:addq   $0x1,(%rsi)   0x4fc775 <_PyEval_EvalCodeWithName+965>:cmp    %edx,%r8d   0x4fc778 <_PyEval_EvalCodeWithName+968>:mov    %rsi,0x18(%rax,%rcx,8)
msg256984 -(view)Author: Serhiy Storchaka (serhiy.storchaka)*(Python committer)Date: 2015-12-25 11:07
There are other bugs in partial() that lead to crash, leak, or invalid behavior. Proposed patch fixes these bugs.
msg258196 -(view)Author: Alyssa Coghlan (ncoghlan)*(Python committer)Date: 2016-01-14 10:38
I didn't do a full review of the C code changes, but the new test cases look good to me, and the changes specifically to partial_setstate also look good.
msg259360 -(view)Author: Raymond Hettinger (rhettinger)*(Python committer)Date: 2016-02-02 05:23
This looks correct.
msg259398 -(view)Author: Serhiy Storchaka (serhiy.storchaka)*(Python committer)Date: 2016-02-02 15:49
Thank you Nick and Raymond for your reviews.
msg259401 -(view)Author: Roundup Robot (python-dev)(Python triager)Date: 2016-02-02 16:46
New changeset542b5744ddc3 by Serhiy Storchaka in branch '3.5':Issue#25945: Fixed bugs in functools.partial.https://hg.python.org/cpython/rev/542b5744ddc3New changeset33109176538d by Serhiy Storchaka in branch 'default':Issue#25945: Fixed bugs in functools.partial.https://hg.python.org/cpython/rev/33109176538dNew changeset628ce2975e29 by Serhiy Storchaka in branch '2.7':Issue#25945: Fixed bugs in functools.partial.https://hg.python.org/cpython/rev/628ce2975e29
History
DateUserActionArgs
2022-04-11 14:58:25adminsetgithub: 70133
2016-02-02 16:59:49serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2016-02-02 16:46:27python-devsetnosy: +python-dev
messages: +msg259401
2016-02-02 15:49:55serhiy.storchakasetmessages: +msg259398
2016-02-02 05:23:42rhettingersetassignee:rhettinger ->serhiy.storchaka
messages: +msg259360
2016-01-14 10:38:08ncoghlansetmessages: +msg258196
2016-01-14 08:02:57serhiy.storchakasetassignee:serhiy.storchaka ->rhettinger
2016-01-14 07:27:01serhiy.storchakalinkissue26104 superseder
2016-01-03 02:03:00martin.panterlinkissue25944 superseder
2015-12-25 11:07:57serhiy.storchakasetfiles: +partial_setstate.patch
keywords: +patch
messages: +msg256984

stage: needs patch -> patch review
2015-12-25 07:08:11serhiy.storchakasetversions: + Python 2.7
nosy: +rhettinger,ncoghlan,serhiy.storchaka

assignee:serhiy.storchaka
components: + Extension Modules, - Library (Lib)
stage: needs patch
2015-12-25 04:17:17Ned Williamsonsetcomponents: + Library (Lib)
2015-12-25 04:16:41Ned Williamsoncreate
Supported byThe Python Software Foundation,
Powered byRoundup
Copyright © 1990-2022,Python Software Foundation
Legal Statements

[8]ページ先頭

©2009-2026 Movatter.jp