
This issue trackerhas been migrated toGitHub, and is currentlyread-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.
Created on2015-12-25 04:16 byNed Williamson, last changed2022-04-11 14:58 byadmin. This issue is nowclosed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| partialpoc2.py | Ned Williamson,2015-12-25 04:16 | |||
| partial_setstate.patch | serhiy.storchaka,2015-12-25 11:07 | review | ||
| 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)*![]() | 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)*![]() | 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)*![]() | Date: 2016-02-02 05:23 | |
This looks correct. | |||
| msg259398 -(view) | Author: Serhiy Storchaka (serhiy.storchaka)*![]() | Date: 2016-02-02 15:49 | |
Thank you Nick and Raymond for your reviews. | |||
| msg259401 -(view) | Author: Roundup Robot (python-dev)![]() | 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 | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:58:25 | admin | set | github: 70133 |
| 2016-02-02 16:59:49 | serhiy.storchaka | set | status: open -> closed resolution: fixed stage: patch review -> resolved |
| 2016-02-02 16:46:27 | python-dev | set | nosy: +python-dev messages: +msg259401 |
| 2016-02-02 15:49:55 | serhiy.storchaka | set | messages: +msg259398 |
| 2016-02-02 05:23:42 | rhettinger | set | assignee:rhettinger ->serhiy.storchaka messages: +msg259360 |
| 2016-01-14 10:38:08 | ncoghlan | set | messages: +msg258196 |
| 2016-01-14 08:02:57 | serhiy.storchaka | set | assignee:serhiy.storchaka ->rhettinger |
| 2016-01-14 07:27:01 | serhiy.storchaka | link | issue26104 superseder |
| 2016-01-03 02:03:00 | martin.panter | link | issue25944 superseder |
| 2015-12-25 11:07:57 | serhiy.storchaka | set | files: +partial_setstate.patch keywords: +patch messages: +msg256984 stage: needs patch -> patch review |
| 2015-12-25 07:08:11 | serhiy.storchaka | set | versions: + Python 2.7 nosy: +rhettinger,ncoghlan,serhiy.storchaka assignee:serhiy.storchaka components: + Extension Modules, - Library (Lib) stage: needs patch |
| 2015-12-25 04:17:17 | Ned Williamson | set | components: + Library (Lib) |
| 2015-12-25 04:16:41 | Ned Williamson | create | |