Skip to content

py: Fix integer overflow in sequence repeat that corrupts memory.#19315

Open
P4P3R-HAK wants to merge 1 commit into
micropython:masterfrom
P4P3R-HAK:fix-sequence-repeat-overflow
Open

py: Fix integer overflow in sequence repeat that corrupts memory.#19315
P4P3R-HAK wants to merge 1 commit into
micropython:masterfrom
P4P3R-HAK:fix-sequence-repeat-overflow

Conversation

@P4P3R-HAK
Copy link
Copy Markdown

Summary

Fixes #19314.

The sequence-repeat operator (seq * n) computed the result size as
len(seq) * n using unchecked size_t arithmetic, allocated a buffer of that
(wrapped) size, and then wrote the full len(seq) * n elements via
mp_seq_multiply(). When the multiplication overflowed size_t the buffer was
under-allocated, causing a heap buffer overflow reachable from pure Python
for str, bytes, list and tuple.

Example (64-bit): (b"A" * 65536) * (2**48) wraps len*n to 0, allocates a
tiny buffer, then copies far past it → crash / memory corruption. On 32-bit
targets the threshold is only 2**32, so an ordinary repeat count is enough
(e.g. (b"x" * 64) * 67108864).

Fix

Check for the overflow before allocating and raise OverflowError (matching
CPython, which raises OverflowError/MemoryError here), instead of corrupting
the heap. The same guard is added to the three callers of mp_seq_multiply():

  • py/objstr.c (str / bytes / bytearray)
  • py/objlist.c
  • py/objtuple.c

Testing

  • New regression test tests/basics/sequence_repeat_overflow.py (portable across
    32/64-bit; output matches CPython).
  • tests/run-tests.py basics545/545 passed (16926 testcases), no regressions.
  • Normal repeats (b"ab"*3, [1,2]*3, (1,2)*3, b"A"*1000000) still work.
  • Verified the original crashing PoCs now raise OverflowError on the standard
    unix build, and that an ASAN build reports a heap-buffer-overflow in
    mp_seq_multiply before the fix.

The repeat operator (seq * n) computed the result size as len(seq) * n
using unchecked size_t arithmetic, allocated a buffer of that (wrapped)
size, and then wrote the full len(seq) * n elements via mp_seq_multiply().
When the multiplication overflowed size_t the buffer was under-allocated,
causing a heap buffer overflow reachable from pure Python for str, bytes,
list and tuple (e.g. b"a" * (n) with a suitable len and n).

Check for the overflow before allocating and raise OverflowError, matching
CPython, instead of corrupting the heap.  Add a regression test.

Signed-off-by: P4P3R-HAK <kbfanta@naver.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.47%. Comparing base (af38ee1) to head (8b200c8).

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #19315   +/-   ##
=======================================
  Coverage   98.47%   98.47%           
=======================================
  Files         176      176           
  Lines       22845    22851    +6     
=======================================
+ Hits        22497    22503    +6     
  Misses        348      348           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jun 5, 2026

Code size report:

Reference:  samd/mphalport: Run events at least once in mp_hal_delay_ms. [af38ee1]
Comparison: py: Fix integer overflow in sequence repeat that corrupts memory. [merge of 8b200c8]
  mpy-cross:  +224 +0.059% 
   bare-arm:   +52 +0.092% 
minimal x86:  +147 +0.079% 
   unix x64:  +160 +0.019% standard
      stm32:  +112 +0.028% PYBV10
      esp32:  +112 +0.006% ESP32_GENERIC[incl +32(data)]
     mimxrt:   +72 +0.018% TEENSY40
        rp2:  +232 +0.025% RPI_PICO_W
       samd:  +156 +0.056% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:  +141 +0.031% VIRT_RV32

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.

Integer overflow in sequence repeat (str/bytes/list/tuple *) causes heap buffer overflow (memory corruption / crash)

1 participant