diff -r 23669bea387e Lib/test/test_descr.py --- a/Lib/test/test_descr.py Fri Mar 01 21:26:04 2013 +0200 +++ b/Lib/test/test_descr.py Sun Mar 03 16:45:33 2013 +0000 @@ -3989,6 +3989,20 @@ C.__name__ = '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): # Testing correct dispatch of subclass overloading __r__... diff -r 23669bea387e Misc/NEWS --- a/Misc/NEWS Fri Mar 01 21:26:04 2013 +0200 +++ b/Misc/NEWS Sun Mar 03 16:45:33 2013 +0000 @@ -10,6 +10,9 @@ Core and Builtins ----------------- +- Issue #16447: Fixed potential segmentation fault when setting __name__ on a + class. + - Issue #1692335: Move initial args assignment to BaseException.__new__ to help pickling of naive subclasses. diff -r 23669bea387e Objects/typeobject.c --- a/Objects/typeobject.c Fri Mar 01 21:26:04 2013 +0200 +++ b/Objects/typeobject.c Sun Mar 03 16:45:33 2013 +0000 @@ -266,10 +266,13 @@ 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; type->tp_name = tp_name; + Py_DECREF(tmp); return 0; }