From 71826cc44bc839aa8e1b62e8848dd93c82b41b8d Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Fri, 22 Dec 2023 17:59:16 +0200 Subject: [PATCH 1/5] gh-111784: Fix two segfaults --- Modules/_elementtree.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c index f9d5793f9b6497..5bf67870767698 100644 --- a/Modules/_elementtree.c +++ b/Modules/_elementtree.c @@ -98,6 +98,7 @@ typedef struct { PyTypeObject *TreeBuilder_Type; PyTypeObject *XMLParser_Type; + PyObject *expat_capsule; struct PyExpat_CAPI *expat_capi; } elementtreestate; @@ -155,6 +156,7 @@ elementtree_clear(PyObject *m) Py_CLEAR(st->ElementIter_Type); Py_CLEAR(st->TreeBuilder_Type); Py_CLEAR(st->XMLParser_Type); + Py_CLEAR(st->expat_capsule); st->expat_capi = NULL; return 0; @@ -175,6 +177,7 @@ elementtree_traverse(PyObject *m, visitproc visit, void *arg) Py_VISIT(st->ElementIter_Type); Py_VISIT(st->TreeBuilder_Type); Py_VISIT(st->XMLParser_Type); + Py_VISIT(st->expat_capsule); return 0; } @@ -3066,6 +3069,7 @@ typedef struct { PyObject *handle_close; elementtreestate *state; + PyObject *elementtree_module; } XMLParserObject; /* helpers */ @@ -3607,7 +3611,11 @@ xmlparser_new(PyTypeObject *type, PyObject *args, PyObject *kwds) self->handle_start = self->handle_data = self->handle_end = NULL; self->handle_comment = self->handle_pi = self->handle_close = NULL; self->handle_doctype = NULL; - self->state = get_elementtree_state_by_type(type); + self->elementtree_module = PyType_GetModuleByDef(type, &elementtreemodule); + assert(self->elementtree_module != NULL); + Py_INCREF(self->elementtree_module); + // See gh-111784 for explanation why is reference to module needed here. + self->state = get_elementtree_state(self->elementtree_module); } return (PyObject *)self; } @@ -3784,6 +3792,7 @@ xmlparser_gc_clear(XMLParserObject *self) EXPAT(st, ParserFree)(parser); } + Py_CLEAR(self->elementtree_module); Py_CLEAR(self->handle_close); Py_CLEAR(self->handle_pi); Py_CLEAR(self->handle_comment); @@ -4343,7 +4352,10 @@ module_exec(PyObject *m) goto error; /* link against pyexpat */ - st->expat_capi = PyCapsule_Import(PyExpat_CAPSULE_NAME, 0); + if (!(st->expat_capsule = _PyImport_GetModuleAttrString("pyexpat", "expat_CAPI"))) + goto error; + if (!(st->expat_capi = PyCapsule_GetPointer(st->expat_capsule, PyExpat_CAPSULE_NAME))) + goto error; if (st->expat_capi) { /* check that it's usable */ if (strcmp(st->expat_capi->magic, PyExpat_CAPI_MAGIC) != 0 || From 44fffc248a711b7f697d14ac2a26110b916ad5d3 Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Sat, 23 Dec 2023 13:18:35 +0200 Subject: [PATCH 2/5] Add NEWS entry --- .../Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst diff --git a/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst b/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst new file mode 100644 index 00000000000000..534ab880c9bb46 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst @@ -0,0 +1,4 @@ +Fix first segfault during deallocation of ``_elementtree.XMLParser`` instances by keeping strong reference +to ``pyexpat`` module in module state for capsule lifetime. +Fix second segfault which happens in the same deallocation process by keeping strong reference +to `_elementtree` module in `XMLParser` structure for `_elementtree` module lifetime. \ No newline at end of file From 234047feb11d922d194f6f982d0c864fdbeb16f3 Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Sat, 23 Dec 2023 13:19:21 +0200 Subject: [PATCH 3/5] Add NEWS entry --- .../next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst b/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst index 534ab880c9bb46..51810255a10129 100644 --- a/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst +++ b/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst @@ -1,4 +1,4 @@ Fix first segfault during deallocation of ``_elementtree.XMLParser`` instances by keeping strong reference to ``pyexpat`` module in module state for capsule lifetime. Fix second segfault which happens in the same deallocation process by keeping strong reference -to `_elementtree` module in `XMLParser` structure for `_elementtree` module lifetime. \ No newline at end of file +to ``_elementtree`` module in ``XMLParser`` structure for ``_elementtree`` module lifetime. \ No newline at end of file From 9a50589a76dae6934999df9df590ff0a289306b2 Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Sat, 23 Dec 2023 13:30:25 +0200 Subject: [PATCH 4/5] Add missing newline --- .../next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst b/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst index 51810255a10129..fea56ab81bca56 100644 --- a/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst +++ b/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst @@ -1,4 +1,4 @@ Fix first segfault during deallocation of ``_elementtree.XMLParser`` instances by keeping strong reference to ``pyexpat`` module in module state for capsule lifetime. Fix second segfault which happens in the same deallocation process by keeping strong reference -to ``_elementtree`` module in ``XMLParser`` structure for ``_elementtree`` module lifetime. \ No newline at end of file +to ``_elementtree`` module in ``XMLParser`` structure for ``_elementtree`` module lifetime. From 328ee441e543ba5aed91425c729b9c6e789d8f1a Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Sat, 23 Dec 2023 13:37:15 +0200 Subject: [PATCH 5/5] Adjust NEWS --- .../next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst b/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst index fea56ab81bca56..51ac0752cfae84 100644 --- a/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst +++ b/Misc/NEWS.d/next/Library/2023-12-23-13-10-42.gh-issue-111784.Nb4L1j.rst @@ -1,3 +1,4 @@ +Fix segfaults in the ``_elementtree`` module. Fix first segfault during deallocation of ``_elementtree.XMLParser`` instances by keeping strong reference to ``pyexpat`` module in module state for capsule lifetime. Fix second segfault which happens in the same deallocation process by keeping strong reference