GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-156939: Fix struct.pack('0p', bytes) by vstinner · Pull Request #157071 · python/cpython

Conversation

@vstinner

@vstinner vstinner commented Sep 7, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

If the Pascal string is empty (size=0), do not write the size prefix. Previously, a NUL byte was written outsize the buffer (buffer overflow).

  • Issue: C API: Detect buffer overflow in PyBytesWriter #156939

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@vstinner
pythongh-156943: Fix struct.pack('0p', bytes)
8b4a48d
If the Pascal string is empty (size=0), do not write the size prefix.
Previously, a NUL byte was written outsize the buffer (buffer
overflow).
@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 bugs and security fixes labels Sep 7, 2026
@bedevere-app bedevere-app Bot added the awaiting core review label Sep 7, 2026
@vstinner vstinner changed the title gh-156943: Fix struct.pack('0p', bytes) gh-156939: Fix struct.pack('0p', bytes) Sep 7, 2026
@bedevere-app bedevere-app Bot mentioned this pull request Sep 7, 2026
C API: Detect buffer overflow in PyBytesWriter #156939
Closed
@vstinner

vstinner commented Sep 7, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

In Python 3.14 and older, struct.pack('0p', b'abc') writes a NUL byte after the bytes contents. But bytes objects allocates an extra byte for a trailing NUL byte, so the buffer overflow doesn't write arbitrary memory. It's just a silent write which doesn't corrupt anything.

On Python 3.15 and newer, struct.pack() uses PyBytesWriter which doesn't allocate an extra trailing NUL byte for small strings (up to 256 bytes). And so a buffer overflow can write outsize PyBytesWriter.small_buffer. In practice, it should write a NUL byte in PyBytesWriter.obj which is a NULL pointer, so it should not corrupt arbitrary memory.

Well, it's better to avoid a buffer overflow anyway :-)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner vstinner added the skip news label Sep 7, 2026
@vstinner

vstinner commented Sep 7, 2026

Copy link
Copy Markdown
Member Author

Ah, I forgot to mention that the 0p format always produces an empty bytes string:

>>> struct.pack('0p', b'abc')
b''
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner

vstinner commented Sep 7, 2026

Copy link
Copy Markdown
Member Author

In Python 3.14 and older, struct.pack('0p', b'abc') writes a NUL byte after the bytes contents. But bytes objects allocates an extra byte for a trailing NUL byte, so the buffer overflow doesn't write arbitrary memory.

Oh, I forgot that Python 3.13 and 3.14 uses the old internal _PyBytesWriter API. struct.pack('0p', b'abc') uses a small buffer in the writer API. The small buffer is between 10 and 512 bytes, so writing a NUL byte a position 0 doesn't corrupt memory. It's just a silent (ignored) write.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner
vstinner merged commit 23525c9 into python:main Sep 7, 2026
61 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@vstinner
vstinner deleted the struct_empty_pascal branch September 7, 2026 19:32
@miss-islington-app

miss-islington-app Bot commented Sep 7, 2026

Copy link
Copy Markdown

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting core review label Sep 7, 2026
@bedevere-app

bedevere-app Bot commented Sep 7, 2026

Copy link
Copy Markdown

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

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

bedevere-app Bot commented Sep 7, 2026

Copy link
Copy Markdown

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

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

bedevere-app Bot commented Sep 7, 2026

Copy link
Copy Markdown

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

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.13 only security fixes label Sep 7, 2026
vstinner added a commit that referenced this pull request Sep 7, 2026
@miss-islington @vstinner
[3.13] gh-156939: Fix struct.pack('0p', bytes) (GH-157071) (#157131)
1c5df82
gh-156939: Fix struct.pack('0p', bytes) (GH-157071)

If the Pascal string is empty (size=0), do not write the size prefix.
Previously, a NUL byte was written outsize the buffer (buffer
overflow). In practice, the write remains into allocated memory
and is silently ignored: no memory is corrupted.
(cherry picked from commit 23525c9)

Co-authored-by: Victor Stinner <[email protected]>
vstinner added a commit that referenced this pull request Sep 7, 2026
@miss-islington @vstinner
[3.14] gh-156939: Fix struct.pack('0p', bytes) (GH-157071) (#157130)
3a27a35
gh-156939: Fix struct.pack('0p', bytes) (GH-157071)

If the Pascal string is empty (size=0), do not write the size prefix.
Previously, a NUL byte was written outsize the buffer (buffer
overflow). In practice, the write remains into allocated memory
and is silently ignored: no memory is corrupted.
(cherry picked from commit 23525c9)

Co-authored-by: Victor Stinner <[email protected]>
@vstinner

vstinner commented Sep 7, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

On Python 3.14 and older, if the struct.pack() output size is 512 bytes, this bug can lead to a buffer overflow writing one NUL byte into the stack memory. Example of code triggering the overflow:

import struct
size = 512
res = struct.pack(f'{size}s0p', b'x' * size, b'ignored')
print(len(res))
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@vstinner vstinner mentioned this pull request Sep 9, 2026
gh-156939: Detect buffer overflow in PyBytesWriter in debug mode #156943
Merged
clin1234 pushed a commit to clin1234/cpython that referenced this pull request Sep 12, 2026
@vstinner @clin1234
pythongh-156939: Fix struct.pack('0p', bytes) (python#157071)
d3aa5bc
If the Pascal string is empty (size=0), do not write the size prefix.
Previously, a NUL byte was written outsize the buffer (buffer
overflow). In practice, the write remains into allocated memory
and is silently ignored: no memory is corrupted.
serhiy-storchaka pushed a commit that referenced this pull request Oct 10, 2026
@miss-islington @vstinner
[3.15] gh-156939: Fix struct.pack('0p', bytes) (GH-157071) (GH-157129)
61d94ed
If the Pascal string is empty (size=0), do not write the size prefix.
Previously, a NUL byte was written outsize the buffer (buffer
overflow). In practice, the write remains into allocated memory
and is silently ignored: no memory is corrupted.
(cherry picked from commit 23525c9)

Co-authored-by: Victor Stinner <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

skip news

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@vstinner
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.