diff options
author | Jelle Zijlstra <jelle.zijlstra@gmail.com> | 2022-05-07 04:01:23 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-07 04:01:23 (GMT) |
commit | 4674b315e555828e5cb15bedcf2c495669670cbb (patch) | |
tree | 6e8024c47bff12cc18d22b4cf78e51d68f5a17a3 /Objects | |
parent | 17f3b5cbfaada66b45422e80c06b0c5f8157a736 (diff) | |
download | cpython-4674b315e555828e5cb15bedcf2c495669670cbb.zip cpython-4674b315e555828e5cb15bedcf2c495669670cbb.tar.gz cpython-4674b315e555828e5cb15bedcf2c495669670cbb.tar.bz2 |
[3.10] gh-92112: Fix crash triggered by an evil custom `mro()` (GH-92113) (#92370)
(cherry picked from commit 85354ed78c0edb6d81a2bd53cabc85e547b8b26e)
Co-authored-by: Alexey Izbyshev <izbyshev@ispras.ru>
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/typeobject.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/Objects/typeobject.c b/Objects/typeobject.c index b3ba120..50f2742 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -369,22 +369,26 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { Py_ssize_t i, n; int custom = !Py_IS_TYPE(type, &PyType_Type); int unbound; - PyObject *mro_meth = NULL; - PyObject *type_mro_meth = NULL; if (custom) { + PyObject *mro_meth, *type_mro_meth; mro_meth = lookup_maybe_method( (PyObject *)type, &PyId_mro, &unbound); - if (mro_meth == NULL) + if (mro_meth == NULL) { goto clear; + } type_mro_meth = lookup_maybe_method( (PyObject *)&PyType_Type, &PyId_mro, &unbound); - if (type_mro_meth == NULL) + if (type_mro_meth == NULL) { + Py_DECREF(mro_meth); goto clear; - if (mro_meth != type_mro_meth) + } + int custom_mro = (mro_meth != type_mro_meth); + Py_DECREF(mro_meth); + Py_DECREF(type_mro_meth); + if (custom_mro) { goto clear; - Py_XDECREF(mro_meth); - Py_XDECREF(type_mro_meth); + } } n = PyTuple_GET_SIZE(bases); for (i = 0; i < n; i++) { @@ -400,8 +404,6 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { } return; clear: - Py_XDECREF(mro_meth); - Py_XDECREF(type_mro_meth); type->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG; type->tp_version_tag = 0; /* 0 is not a valid version tag */ } |