** SIGSEGV in `ST_LINKInterface::programMemory` during `--incremental` flash with two STLINK-V3 probes connected
Product: STM32CubeProgrammer 2.22.0 (Linux x86-64) Interface: SWD / STLINK-V3 (dual probes) Target: STM32F427 (DEV_ID 0x419)
Description
Running --incremental flash against one STLINK-V3 probe while a second STLINK-V3 is physically connected (but not commanded) produces a deterministic SIGSEGV inside ST_LINKInterface::programMemory.
Call chain at crash:
DebugInterface::programBufferFlashLoader (@ 0x206400)
FlashLoaderMng::Loader_WriteRange
ST_LINKInterface::programMemory ← SIGSEGV @ 0x727b81
Root cause: use-after-free on Target::loaders
Target::loaders is a BSS-global loader table shared across all code in the process. When the second probe is plugged in, the library's internal USB hotplug callback fires, rescans the bus, and rebuilds — freeing — the loader table while the incremental flash write loop holds a pointer into it. There is no lock observed on the table.
The sequence at the crash site (DebugInterface::programBufferFlashLoader @ 0x206400):
206631: mov 0x40(%rsp),%rdi ; load QString internal buffer ptr
206636: call free@plt ; free buffer #1
20664e: call _ZdlPv@plt ; operator delete (buffer #2)
...
2064df: mov _ZN6Target7loadersE(%rip),%rbx ; load global loader table ptr
206663: mov (%rbx),%rax ; deref table base
20666f: mov (%rdi,%rax,8),%rdi ; index into loader array
206690: mov (%rdi),%rax ; load vtable ptr ← UAF: object freed by hotplug
206697: call *0x18(%rax) ; virtual dispatch → programMemory → SIGSEGV
Between loading the table pointer and dereferencing the loader object's vtable, the hotplug callback can free and reallocate the table. The stale buffer pointer is subsequently passed to submit_bulk_transfer; the kernel rejects it with EFAULT (errno=14). The code does not null-check the EFAULT return, and the next dereference crashes.
Reproduction
Minimum repro:
- Connect two STLINK-V3 probes to the same host.
- Run
--incrementalflash against one of them:
STM32_Programmer_CLI -c port=SWD freq=24000 mode=UR reset=HWrst sn=<SN1> \
-d firmware.elf incremental -hardRst
The second probe need not be commanded — its presence on the USB bus is sufficient to trigger hotplug events during the flash operation.
The crash is deterministic across multiple runs. The libusb errno=14 appears in stderr immediately before the signal.
Alternative trigger: USB authorization thrashing on any second device (/sys/bus/usb/devices/.../authorized 0→1 in a tight loop) while the write is in flight produces the same race.
Scope: incremental mode only (confirmed)
