Skip to content

gh-126033: fix a crash in xml.etree.ElementTree.Element.remove when concurrent mutations happen #126124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Mar 31, 2025

Conversation

picnixz
Copy link
Member

@picnixz picnixz commented Oct 29, 2024

No need for versioning. Holding a strong reference on the child being compared is enough if we additionally check that the number of children is not changed after the comparison.

The test coverage could be refined but I don't think I need to overcomplicate it even more. I still think we can have a UAF because when one clears the list in __eq__ but I couldn't find a way to trigger it so I just increfed the item before calling __eq__. If anyone thinks it's not needed, please tell me why.

The patch for find* may be more complicated, which is why I splitted the task into three (one for introducing the versioning so that we can work on those failures in parallel).

@picnixz picnixz force-pushed the fix/xml-evil-remove-126033 branch from bb4f6d2 to 59ade8f Compare October 29, 2024 12:33
Copy link
Member

@serhiy-storchaka serhiy-storchaka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is adding version necessary? Would not keeping a strong reference to a child be enough? Look at the list.remove() code.

@picnixz
Copy link
Member Author

picnixz commented Dec 6, 2024

Would not keeping a strong reference to a child be enough? Look at the list.remove() code.

Oh yes. I'll try using this one as a basis.

@picnixz
Copy link
Member Author

picnixz commented Dec 6, 2024

Would not keeping a strong reference to a child be enough? Look at the list.remove() code.

Ah I know why I couldn't make it work! it's because the children is not a list itself, but just a huge memory area that was dynamically allocated using PyMem_Malloc. What do you suggest I do?

@serhiy-storchaka
Copy link
Member

The list storage is also just a huge memory area that was dynamically allocated using PyMem_Malloc. I do not see difference.

At worst, you can get different exceptions (or no exception) in C and Python implementations, but this is fine.

@picnixz
Copy link
Member Author

picnixz commented Dec 6, 2024

The list storage is also just a huge memory area that was dynamically allocated using PyMem_Malloc. I do not see difference.

The difference is that the list object uses Py_SIZE but it's not possible to use this on the current implementation of element trees (or is there?)

@serhiy-storchaka
Copy link
Member

Py_SIZE or self->extra->length -- there is not much difference between them. Both just read a word from memory. You may need to check that self->extra was not set to NULL during iteration, this is the only difference.

@picnixz
Copy link
Member Author

picnixz commented Dec 6, 2024

Py_SIZE or self->extra->length -- there is not much difference between them

I'm pretty sure I first tried using INCREF/DECREF as usual and encountered an issue with that but I can't remember how. I'll try reproducing this tomorrow.

@picnixz picnixz marked this pull request as draft December 6, 2024 18:03
@picnixz picnixz marked this pull request as ready for review December 8, 2024 13:08
@picnixz picnixz requested a review from vstinner February 12, 2025 11:21
@picnixz
Copy link
Member Author

picnixz commented Mar 14, 2025

@vstinner @serhiy-storchaka friendly ping in case you forgot about this one

@vstinner
Copy link
Member

As I wrote, I don't think that 200 lines of tests are needed. I would prefer way less tests.

@picnixz
Copy link
Member Author

picnixz commented Mar 14, 2025

I can remove the special test case which makes the test explode as it's only the Python implementation if you want. It would reduce the test by half at least (most of the line length is taken by comments that are needed to explain the discrepency between the Python and the C implementation).

@picnixz
Copy link
Member Author

picnixz commented Mar 15, 2025

@vstinner I've removed the pedantic check. However, we still need to have that much of tests because del root[:] and root.clear() behave differently although they should do the same. The reproducer I had did not make crash del root[:], but it made crash root.clear().

Copy link
Member

@vstinner vstinner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. The C code change LGTM, I didn't review the tests.

@picnixz picnixz merged commit bab1398 into python:main Mar 31, 2025
42 checks passed
@miss-islington-app
Copy link

Thanks @picnixz for the PR 🌮🎉.. I'm working now to backport this PR to: 3.12, 3.13.
🐍🍒⛏🤖

@picnixz picnixz deleted the fix/xml-evil-remove-126033 branch March 31, 2025 10:31
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Mar 31, 2025
…en concurrent mutations happen (pythonGH-126124)

(cherry picked from commit bab1398)

Co-authored-by: Bénédikt Tran <[email protected]>
@bedevere-app
Copy link

bedevere-app bot commented Mar 31, 2025

GH-131929 is a backport of this pull request to the 3.13 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.13 bugs and security fixes label Mar 31, 2025
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Mar 31, 2025
…en concurrent mutations happen (pythonGH-126124)

(cherry picked from commit bab1398)

Co-authored-by: Bénédikt Tran <[email protected]>
@bedevere-app
Copy link

bedevere-app bot commented Mar 31, 2025

GH-131930 is a backport of this pull request to the 3.12 branch.

@bedevere-app bedevere-app bot removed the needs backport to 3.12 only security fixes label Mar 31, 2025
picnixz added a commit that referenced this pull request Mar 31, 2025
…hen concurrent mutations happen (GH-126124) (#131929)

gh-126033: fix UAF in `xml.etree.ElementTree.Element.remove` when concurrent mutations happen (GH-126124)
(cherry picked from commit bab1398)

Co-authored-by: Bénédikt Tran <[email protected]>
picnixz added a commit that referenced this pull request Mar 31, 2025
…hen concurrent mutations happen (GH-126124) (#131930)

gh-126033: fix UAF in `xml.etree.ElementTree.Element.remove` when concurrent mutations happen (GH-126124)
(cherry picked from commit bab1398)

Co-authored-by: Bénédikt Tran <[email protected]>
seehwan pushed a commit to seehwan/cpython that referenced this pull request Apr 16, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants