Skip to content

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

Merged
vstinner merged 16 commits into
python:mainfrom
Joekrry:fix-mmap-setitem-resize-reentrancy
Sep 23, 2026
Merged

vstinner merged 16 commits into
python:mainfrom
Joekrry:fix-mmap-setitem-resize-reentrancy

Conversation

@Joekrry

@Joekrry Joekrry commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

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
Contributor 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 only 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 :-(

@vstinner
vstinner merged commit 09bf4c5 into python:main Sep 23, 2026
64 checks passed
@miss-islington-app

Copy link
Copy Markdown

Thanks @Joekrry for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14, 3.15.
🐍🍒⛏🤖

@miss-islington-app

Copy link
Copy Markdown

Sorry, @Joekrry and @vstinner, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 09bf4c525871db3ad02c8a1359da5cf0668f27b0 3.13

@bedevere-app

bedevere-app Bot commented Sep 23, 2026

Copy link
Copy Markdown

GH-158026 is a backport of this pull request to the 3.15 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label Sep 23, 2026
@bedevere-app

bedevere-app Bot commented Sep 23, 2026

Copy link
Copy Markdown

GH-158027 is a backport of this pull request to the 3.14 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label Sep 23, 2026
@bedevere-app

bedevere-app Bot commented Sep 23, 2026

Copy link
Copy Markdown

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

@bedevere-app bedevere-app Bot removed the needs backport to 3.13 only security fixes label Sep 23, 2026
@vstinner

Copy link
Copy Markdown
Member

Merged. Thanks for the fix @Joekrry!

@Joekrry
Joekrry deleted the fix-mmap-setitem-resize-reentrancy branch September 23, 2026 20:15
vstinner added a commit that referenced this pull request Sep 23, 2026
…157438) (#158028)

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

Fix out-of-bounds write in mmap.mmap.__setitem__() that could occur
when converting the index or the assigned value (via __index__()
for a single item, or via the buffer protocol for a slice) resized or closed
the mmap object during the assignment.


(cherry picked from commit 09bf4c5)

Co-authored-by: Joseph Kerry <joerkerry@gmail.com>
vstinner added a commit that referenced this pull request Sep 23, 2026
…H-157438) (#158027)

gh-157335: Fix out-of-bounds write in mmap.mmap.__setitem__ (GH-157438)

Fix out-of-bounds write in mmap.mmap.__setitem__() that could occur
when converting the index or the assigned value (via __index__()
for a single item, or via the buffer protocol for a slice) resized or closed
the mmap object during the assignment.
(cherry picked from commit 09bf4c5)

Co-authored-by: Joseph Kerry <joerkerry@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
hugovk pushed a commit that referenced this pull request Sep 28, 2026
…H-157438) (#158026)

Co-authored-by: Joseph Kerry <joerkerry@gmail.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mmap.mmap.__setitem__ crashes when concurrently resized

3 participants