diff --git a/Lib/test/crashers/borrowed_ref_3.py b/Lib/test/crashers/borrowed_ref_3.py deleted file mode 100644 index f241108635c..00000000000 --- a/Lib/test/crashers/borrowed_ref_3.py +++ /dev/null @@ -1,14 +0,0 @@ -""" -PyDict_GetItem() returns a borrowed reference. -There are probably a number of places that are open to attacks -such as the following one, in bltinmodule.c:min_max(). -""" - -class KeyFunc(object): - def __call__(self, n): - del d['key'] - return 1 - - -d = {'key': KeyFunc()} -min(range(10), **d) diff --git a/Lib/test/crashers/borrowed_ref_4.py b/Lib/test/crashers/borrowed_ref_4.py deleted file mode 100644 index d1fd8aad3a8..00000000000 --- a/Lib/test/crashers/borrowed_ref_4.py +++ /dev/null @@ -1,28 +0,0 @@ -""" -PyDict_GetItem() returns a borrowed reference. -This attack is against ceval.c:IMPORT_NAME, which calls an -object (__builtin__.__import__) without holding a reference to it. -""" - -import types -import __builtin__ - - -class X(object): - def __getattr__(self, name): - # this is called with name == '__bases__' by PyObject_IsInstance() - # during the unbound method call -- it frees the unbound method - # itself before it invokes its im_func. - del __builtin__.__import__ - return () - -pseudoclass = X() - -class Y(object): - def __call__(self, *args): - # 'self' was freed already - print self, args - -# make an unbound method -__builtin__.__import__ = types.MethodType(Y(), None, (pseudoclass, str)) -import spam diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 9a3135634e0..444fc1e7183 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -1245,11 +1245,14 @@ min_max(PyObject *args, PyObject *kwds, int op) "%s() got an unexpected keyword argument", name); return NULL; } + Py_INCREF(keyfunc); } it = PyObject_GetIter(v); - if (it == NULL) + if (it == NULL) { + Py_XDECREF(keyfunc); return NULL; + } maxitem = NULL; /* the result */ maxval = NULL; /* the value associated with the result */ @@ -1298,6 +1301,7 @@ min_max(PyObject *args, PyObject *kwds, int op) else Py_DECREF(maxval); Py_DECREF(it); + Py_XDECREF(keyfunc); return maxitem; Fail_it_item_and_val: @@ -1308,6 +1312,7 @@ Fail_it: Py_XDECREF(maxval); Py_XDECREF(maxitem); Py_DECREF(it); + Py_XDECREF(keyfunc); return NULL; } diff --git a/Python/ceval.c b/Python/ceval.c index 5433b882bda..3e0ff769441 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2066,6 +2066,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) "__import__ not found"); break; } + Py_INCREF(x); v = POP(); u = TOP(); if (PyInt_AsLong(u) != -1 || PyErr_Occurred()) @@ -2087,11 +2088,14 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) Py_DECREF(u); if (w == NULL) { u = POP(); + Py_DECREF(x); x = NULL; break; } READ_TIMESTAMP(intr0); - x = PyEval_CallObject(x, w); + v = x; + x = PyEval_CallObject(v, w); + Py_DECREF(v); READ_TIMESTAMP(intr1); Py_DECREF(w); SET_TOP(x);