Skip to content

re.sub callback can retain a stack-backed match object #19756

Description

@yet-another-agent

Port, board and hardware

Unix port on Linux ARM64.

MicroPython version

MicroPython a129b2fba1 on 2026-10-10; linux [GCC 14.2.0] version (a129b2fba1a3348088c94d0462eef16d20874dea)

Summary

The match object passed to a callable replacement can escape the callback even though its backing object is stack allocated. Accessing the retained match later jumps through invalid state.

Build: VARIANT=coverage with the repository's official ASan flags: -fsanitize=address --param asan-use-after-return=0 -DMP_ASAN=1.

Reproduction

A replacement callback retains and later accesses its match argument

import re

keep = []


def grab(m):
    keep.append(m)
    return "x"


re.sub("a", grab, "a")
print(type(keep[0]))
keep[0].group(0)

Observed: SUMMARY: AddressSanitizer: SEGV ../../py/runtime.c:1204 in mp_load_method_maybe

Complete ASan output
<class 'match'>
AddressSanitizer:DEADLYSIGNAL
=================================================================
==73==ERROR: AddressSanitizer: SEGV on unknown address 0x040fff53a1ea (pc 0xaaaae730eb5c bp 0xffffd4e87b90 sp 0xffffd4e87b90 T0)
==73==The signal is caused by a READ memory access.
    #0 0xaaaae730eb5c in mp_load_method_maybe ../../py/runtime.c:1204
    #1 0xaaaae730fa18 in mp_load_method ../../py/runtime.c:1231
    #2 0xaaaae737ef44 in mp_execute_bytecode ../../py/vm.c:441
    #3 0xaaaae7330c64 in fun_bc_call ../../py/objfun.c:294
    #4 0xaaaae7310618 in mp_call_function_n_kw ../../py/runtime.c:719
    #5 0xaaaae7314720 in mp_call_function_0 ../../py/runtime.c:693
    #6 0xaaaae749a60c in parse_compile_execute ../../shared/runtime/pyexec.c:137
    #7 0xaaaae749b774 in pyexec_file ../../shared/runtime/pyexec.c:739
    #8 0xaaaae74903f0 in do_file /src/ports/unix/main.c:269
    #9 0xaaaae7491a18 in main_ /src/ports/unix/main.c:692
    #10 0xaaaae7492000 in main /src/ports/unix/main.c:452
    #11 0xffff7fa62258  (/lib/aarch64-linux-gnu/libc.so.6+0x22258) (BuildId: 4c1eca4527d1163b2dde55860b69f270158febb4)
    #12 0xffff7fa62338 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x22338) (BuildId: 4c1eca4527d1163b2dde55860b69f270158febb4)
    #13 0xaaaae72cccac in _start (/workspace/work/micropython-current/ports/unix/build-asan-linux-official/micropython+0x19ccac) (BuildId: d745232daadafece431463287d3aa5e506209b85)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV ../../py/runtime.c:1204 in mp_load_method_maybe
==73==ABORTING

Expected behaviour

The operation should complete safely or raise a Python exception without terminating the interpreter.

Observed behaviour

Each reproducer terminates the interpreter under AddressSanitizer in 3/3 runs.

Additional information

No exploitability claim is intended; these are interpreter robustness failures reachable from Python code.

Tracking references: MicroPython-23.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions