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
List operations retain element storage and bounds across calls to user-defined __eq__. If the callback clears or shrinks a participating list, the operation later reads invalid elements.
Build: VARIANT=coverage with the repository's official ASan flags: -fsanitize=address --param asan-use-after-return=0 -DMP_ASAN=1.
Reproduction
list.count continues after __eq__ clears the searched list
class Boom:
def __eq__(self, other):
# Re-entrant mutation: free the list backing store while count() still uses it.
lst.clear()
return False
lst = [Boom(), 1]
lst.count(0)
Observed: SUMMARY: AddressSanitizer: SEGV ../../py/obj.c:233 in mp_obj_equal_not_equal
Complete ASan output
AddressSanitizer:DEADLYSIGNAL
=================================================================
==37==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0xaaaab110fbc4 bp 0xffffccce3020 sp 0xffffccce3020 T0)
==37==The signal is caused by a READ memory access.
==37==Hint: address points to the zero page.
#0 0xaaaab110fbc4 in mp_obj_equal_not_equal ../../py/obj.c:233
#1 0xaaaab111057c in mp_obj_equal ../../py/obj.c:303
#2 0xaaaab11504b0 in mp_seq_count_obj ../../py/sequence.c:209
#3 0xaaaab1127e40 in list_count ../../py/objlist.c:369
#4 0xaaaab11204cc in fun_builtin_2_call ../../py/objfun.c:82
#5 0xaaaab1100618 in mp_call_function_n_kw ../../py/runtime.c:719
#6 0xaaaab1100fbc in mp_call_method_n_kw ../../py/runtime.c:735
#7 0xaaaab11678f4 in mp_execute_bytecode ../../py/vm.c:1069
#8 0xaaaab1120c64 in fun_bc_call ../../py/objfun.c:294
#9 0xaaaab1100618 in mp_call_function_n_kw ../../py/runtime.c:719
#10 0xaaaab1104720 in mp_call_function_0 ../../py/runtime.c:693
#11 0xaaaab128a60c in parse_compile_execute ../../shared/runtime/pyexec.c:137
#12 0xaaaab128b774 in pyexec_file ../../shared/runtime/pyexec.c:739
#13 0xaaaab12803f0 in do_file /src/ports/unix/main.c:269
#14 0xaaaab1281a18 in main_ /src/ports/unix/main.c:692
#15 0xaaaab1282000 in main /src/ports/unix/main.c:452
#16 0xffffb1a62258 (/lib/aarch64-linux-gnu/libc.so.6+0x22258) (BuildId: 4c1eca4527d1163b2dde55860b69f270158febb4)
#17 0xffffb1a62338 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x22338) (BuildId: 4c1eca4527d1163b2dde55860b69f270158febb4)
#18 0xaaaab10bccac 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/obj.c:233 in mp_obj_equal_not_equal
==37==ABORTING
List comparison continues after __eq__ shrinks the right-hand list
class Boom:
def __eq__(self, other):
rhs.pop()
return True
rhs = [Boom(), 1]
lhs = [Boom(), 1]
lhs == rhs
Observed: SUMMARY: AddressSanitizer: SEGV ../../py/obj.c:247 in mp_obj_equal_not_equal
Complete ASan output
AddressSanitizer:DEADLYSIGNAL
=================================================================
==70==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0xaaaadda4fc28 bp 0xffffec615a50 sp 0xffffec615a50 T0)
==70==The signal is caused by a READ memory access.
==70==Hint: address points to the zero page.
#0 0xaaaadda4fc28 in mp_obj_equal_not_equal ../../py/obj.c:247
#1 0xaaaadda5057c in mp_obj_equal ../../py/obj.c:303
#2 0xaaaadda90068 in mp_seq_cmp_objs ../../py/sequence.c:153
#3 0xaaaadda69648 in list_binary_op ../../py/objlist.c:152
#4 0xaaaadda5030c in mp_obj_equal_not_equal ../../py/obj.c:280
#5 0xaaaadda45594 in mp_binary_op ../../py/runtime.c:403
#6 0xaaaaddaa562c in mp_execute_bytecode ../../py/vm.c:1302
#7 0xaaaadda60c64 in fun_bc_call ../../py/objfun.c:294
#8 0xaaaadda40618 in mp_call_function_n_kw ../../py/runtime.c:719
#9 0xaaaadda44720 in mp_call_function_0 ../../py/runtime.c:693
#10 0xaaaaddbca60c in parse_compile_execute ../../shared/runtime/pyexec.c:137
#11 0xaaaaddbcb774 in pyexec_file ../../shared/runtime/pyexec.c:739
#12 0xaaaaddbc03f0 in do_file /src/ports/unix/main.c:269
#13 0xaaaaddbc1a18 in main_ /src/ports/unix/main.c:692
#14 0xaaaaddbc2000 in main /src/ports/unix/main.c:452
#15 0xffff7f062258 (/lib/aarch64-linux-gnu/libc.so.6+0x22258) (BuildId: 4c1eca4527d1163b2dde55860b69f270158febb4)
#16 0xffff7f062338 in __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x22338) (BuildId: 4c1eca4527d1163b2dde55860b69f270158febb4)
#17 0xaaaadd9fccac 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/obj.c:247 in mp_obj_equal_not_equal
==70==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-11, MicroPython-22.
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
List operations retain element storage and bounds across calls to user-defined
__eq__. If the callback clears or shrinks a participating list, the operation later reads invalid elements.Build:
VARIANT=coveragewith the repository's official ASan flags:-fsanitize=address --param asan-use-after-return=0 -DMP_ASAN=1.Reproduction
list.countcontinues after__eq__clears the searched listObserved:
SUMMARY: AddressSanitizer: SEGV ../../py/obj.c:233 in mp_obj_equal_not_equalComplete ASan output
List comparison continues after
__eq__shrinks the right-hand listObserved:
SUMMARY: AddressSanitizer: SEGV ../../py/obj.c:247 in mp_obj_equal_not_equalComplete ASan output
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-11, MicroPython-22.