Kaydet (Commit) f794b143 authored tarafından Mark Dickinson's avatar Mark Dickinson

Issue #16447: Fix potential segfault when setting __name__ on a class.

üst 6fa83f99
...@@ -4136,6 +4136,20 @@ order (MRO) for bases """ ...@@ -4136,6 +4136,20 @@ order (MRO) for bases """
C.__name__ = 'D.E' C.__name__ = 'D.E'
self.assertEqual((C.__module__, C.__name__), (mod, 'D.E')) self.assertEqual((C.__module__, C.__name__), (mod, 'D.E'))
def test_evil_type_name(self):
# A badly placed Py_DECREF in type_set_name led to arbitrary code
# execution while the type structure was not in a sane state, and a
# possible segmentation fault as a result. See bug #16447.
class Nasty(str):
def __del__(self):
C.__name__ = "other"
class C(object):
pass
C.__name__ = Nasty("abc")
C.__name__ = "normal"
def test_subclass_right_op(self): def test_subclass_right_op(self):
# Testing correct dispatch of subclass overloading __r<op>__... # Testing correct dispatch of subclass overloading __r<op>__...
......
...@@ -17,6 +17,9 @@ Build ...@@ -17,6 +17,9 @@ Build
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #16447: Fixed potential segmentation fault when setting __name__ on a
class.
- Issue #17610: Don't rely on non-standard behavior of the C qsort() function. - Issue #17610: Don't rely on non-standard behavior of the C qsort() function.
Library Library
......
...@@ -225,6 +225,7 @@ static int ...@@ -225,6 +225,7 @@ static int
type_set_name(PyTypeObject *type, PyObject *value, void *context) type_set_name(PyTypeObject *type, PyObject *value, void *context)
{ {
PyHeapTypeObject* et; PyHeapTypeObject* et;
PyObject *tmp;
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
...@@ -253,10 +254,13 @@ type_set_name(PyTypeObject *type, PyObject *value, void *context) ...@@ -253,10 +254,13 @@ type_set_name(PyTypeObject *type, PyObject *value, void *context)
Py_INCREF(value); Py_INCREF(value);
Py_DECREF(et->ht_name); /* Wait until et is a sane state before Py_DECREF'ing the old et->ht_name
value. (Bug #16447.) */
tmp = et->ht_name;
et->ht_name = value; et->ht_name = value;
type->tp_name = PyString_AS_STRING(value); type->tp_name = PyString_AS_STRING(value);
Py_DECREF(tmp);
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment