Skip to content

Conversation

@cmaloney
Copy link
Contributor

@cmaloney cmaloney commented Nov 10, 2025

Account for when self->pos is equal to PY_SSIZE_T_MAX. The length of read was correctly set to zero but the asserts assumed self->pos couldn't reach PY_SSIZE_T_MAX. Return early to avoid edge cases.

Account for when self->pos is equal to PY_SSIZE_T_MAX. The length of
read was correctly set to zero but the asserts assumed
self->pos couldn't reach PY_SSIZE_T_MAX. Return early to avoid edge
cases.
For `read_bytes_lock_held` the `size` parameter is always set to 0 by calling
code currently if self->pos > self->string_size. I added a range check for
self->pos as an extra safety as codepaths chagne but can remove if it's too much.

`write_bytes_lock_held`: `endpos` is a `size_t` so can hold
`2 * PY_SSIZE_T_MAX`. Value is bounds checked in `resize_buffer_lock_held`.

A number of cases use `scan_eol_lock_held` to move forward. That has code which
checks `self->pos >= self->string_size` and returns `0`. Callsites all seem to
handle that correctly.
@cmaloney
Copy link
Contributor Author

I audited the codepaths which did self->pos + buffer.

For read_bytes_lock_held the size parameter is always set to 0 by calling code currently if self->pos > self->string_size. I added a range check for self->pos as an extra safety as codepaths change but can remove if it's too much.

write_bytes_lock_held: endpos is a size_t so can hold 2 * PY_SSIZE_T_MAX. Value is bounds checked in resize_buffer_lock_held.

A number of cases use scan_eol_lock_held to move forward. That has code which checks self->pos >= self->string_size and returns 0. Callers seem to handle that correctly (early exit or call read_bytes_lock_held)..

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.

LGTM. 👍

@serhiy-storchaka serhiy-storchaka merged commit 7d54374 into python:main Nov 12, 2025
50 checks passed
@serhiy-storchaka serhiy-storchaka added needs backport to 3.13 bugs and security fixes needs backport to 3.14 bugs and security fixes labels Nov 12, 2025
@miss-islington-app
Copy link

Thanks @cmaloney for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13.
🐍🍒⛏🤖

@miss-islington-app
Copy link

Thanks @cmaloney for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

@miss-islington-app
Copy link

Sorry, @cmaloney and @serhiy-storchaka, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker 7d54374f9c7d91e0ef90c4ad84baf10073cf1d8a 3.13

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Nov 12, 2025
Fix error in assertion which causes failure if pos is equal to PY_SSIZE_T_MAX.
Fix undefined behavior in read() and readinto() if pos is larger that the size
of the underlying buffer.
(cherry picked from commit 7d54374)

Co-authored-by: Cody Maloney <cmaloney@users.noreply.github.com>
@bedevere-app
Copy link

bedevere-app bot commented Nov 12, 2025

GH-141457 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 Nov 12, 2025
@serhiy-storchaka
Copy link
Member

@cmaloney, could you please create a backport to 3.13 manually?

serhiy-storchaka pushed a commit that referenced this pull request Nov 12, 2025
…H-141457)

Fix error in assertion which causes failure if pos is equal to PY_SSIZE_T_MAX.
Fix undefined behavior in read() and readinto() if pos is larger that the size
of the underlying buffer.
(cherry picked from commit 7d54374)

Co-authored-by: Cody Maloney <cmaloney@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs backport to 3.13 bugs and security fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants