Skip to content

gh-157335: Fix out-of-bounds write in mmap.mmap.__setitem__ - #157438

Open
Joekrry wants to merge 16 commits into
python:mainfrom
Joekrry:fix-mmap-setitem-resize-reentrancy
Open

Joekrry wants to merge 16 commits into
python:mainfrom
Joekrry:fix-mmap-setitem-resize-reentrancy

Conversation

@Joekrry

@Joekrry Joekrry commented Sep 13, 2026

Copy link
Copy Markdown

Assigning to a single index in mmap.mmap.__setitem__ validates the index against the object's size, then converts the assigned value via PyNumber_AsSsize_t(). That conversion can invoke arbitrary Python code through __index__(), and if that code calls mmap.resize() to shrink the mapping, the previously validated index can point past the end of the new, smaller buffer — causing an out-of-bounds write.

This re-validates the index against the mmap's current size after the value conversion, right alongside the existing CHECK_VALID() check that already accounts for reentrancy at that point.

Fixes gh-157335.

…Assigning to a single index causes mmap.mmap.__setitem__ to validate the index against the object's size, which then converts the assigned value via PyNumber_AsSsize_t(). This invokes arbitrary python code via __index__(). mmap.resize(), which shrinks mapping could point past the end fo the new buffer causing an out of bounds error write.
@python-cla-bot

python-cla-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

Comment thread Modules/mmapmodule.c Outdated
Comment on lines +1690 to +1696
/* value's __index__ may have resized the mmap, invalidating
* the earlier bounds check on i. */
if (i >= self->size) {
PyErr_SetString(PyExc_IndexError,
"mmap index out of range");
return -1;
}

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.

I think we can have the same issue in the slice-branch when doing PyObject_GetBuffer(). So instead, we could make the checks inside the safe_byte_copy and safe_memcpy functions. Though I don't know if it's an overkill. Can you verify that the slice pah is also not affected by adding tests.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Yeah, I fixed the slice path so PyObject_GetBuffer is called first, then computes bounds with PySlice_AdjustIndices against the size after that call. Added a test for this as well.

I didn't move the checks because the check still has to occur at the call.

Hopefully my understanding of this is correct

Comment thread Modules/mmapmodule.c Outdated
Fix the same reentrancy issue in the slice-assignment path: acquiring
the value's buffer (e.g. via a __buffer__ method) can also run
arbitrary code that resizes the mmap, invalidating the previously
computed slice bounds. Re-validate the bounds after acquiring the
buffer, before copying into the mapping.

Clarify why the single-item path still needs a bounds check both
before and after converting the value: the earlier check preserves
existing error precedence (IndexError before TypeError, per
test_basic), while the later one is a narrow revalidation of just the
upper bound.
Comment thread Lib/test/test_mmap.py
Comment thread Modules/mmapmodule.c Outdated

@vstinner vstinner left a comment

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.

Thanks, the PR looks better with checks moved after functions which can call arbitrary Python code. New review: you can now remove redundant CHECK_VALID() check.

Comment thread Modules/mmapmodule.c Outdated
Comment thread Modules/mmapmodule.c Outdated
Comment thread Misc/NEWS.d/next/Library/2026-09-13-15-58-28.gh-issue-157335.efaMah.rst Outdated
Comment thread Lib/test/test_mmap.py Outdated
Comment thread Lib/test/test_mmap.py Outdated
@vstinner vstinner added needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes needs backport to 3.15 pre-release feature fixes, bugs and security fixes labels Sep 15, 2026

@vstinner vstinner left a comment

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.

LGTM.

@serhiy-storchaka: Do you want to double check this mmap fix?

@Joekrry: I'm not sure why you're merging the main branch into your branch so often, it's not need and it makes the review harder to follow :-(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting merge needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes needs backport to 3.15 pre-release feature fixes, bugs and security fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mmap.mmap.__setitem__ crashes when concurrently resized

3 participants