Skip to content

gh-142665: fix UAF when accessing a memoryview concurrently mutates the underlying buffer#143324

Open
picnixz wants to merge 1 commit intopython:mainfrom
picnixz:fix/memory/uaf-in-slicing-142665
Open

gh-142665: fix UAF when accessing a memoryview concurrently mutates the underlying buffer#143324
picnixz wants to merge 1 commit intopython:mainfrom
picnixz:fix/memory/uaf-in-slicing-142665

Conversation

@picnixz
Copy link
Copy Markdown
Member

@picnixz picnixz commented Jan 1, 2026

This fix actually changes the existing behavior but messing up with the memoryview while still being accessed is honestly a poor design choice and I don't know when it'd be legitimate to support bad slicing.

return NULL;

if (init_slice(&sliced->view, key, 0) < 0) {
self->exports++;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you add a comment explaining the purpose of the exports++? Add a reference to the GitHub issue (gh-142665:).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ah, I think I wasn't consistent in my reviews or in my commits. I thought the commit history would have been enough for that. But sure I can a comment

if (init_slice(&sliced->view, key, 0) < 0) {
self->exports++;
int rc = init_slice(&sliced->view, key, 0);
self->exports--;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we go this way, should not we call init_len() and init_flags() while export is incremented?

Also, we can have a similar issue with memory_item_multi().

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Also, memory_ass_sub() can have the same issue.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

For ass_sub, there is:

        /* rvalue must be an exporter */
        if (PyObject_GetBuffer(value, &src, PyBUF_FULL_RO) < 0)
            return ret;

so it's already protected I think

Copy link
Copy Markdown
Member Author

@picnixz picnixz Jan 12, 2026

Choose a reason for hiding this comment

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

But I wasn't aware of memory_item_multi which uses ptr_from_tuple and this looks like vulnerable.

Copy link
Copy Markdown
Member Author

@picnixz picnixz Jan 12, 2026

Choose a reason for hiding this comment

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

If we go this way, should not we call init_len() and init_flags() while export is incremented?

Strictly speaking no because those functions don't call any Python code, unless there are some invariants I'm not aware of

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

PyObject_GetBuffer() is called for source, not for destination. Could not the destination be released while we calculate a slice?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Hum. I actually tried this one. Maybe. I won't be much available for the next two weeks though so this will need to wait a bit!

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.

3 participants