diff --git a/CHANGES b/CHANGES index 6d0f3e1bf..8574d69cb 100644 --- a/CHANGES +++ b/CHANGES @@ -34,6 +34,7 @@ Bugfixes: - Qt: Fix multiplayer windows opening as the wrong size - Qt: Fix controllers sometimes not loading the right profile - GBA: Fix hang when loading a savestate if sync to video is enabled + - Debugger: Fix use-after-free in breakpoint clearing code Misc: - Qt: Show multiplayer numbers in window title - Qt: Handle saving input settings better diff --git a/src/debugger/debugger.c b/src/debugger/debugger.c index 9ac053115..f886db969 100644 --- a/src/debugger/debugger.c +++ b/src/debugger/debugger.c @@ -149,11 +149,14 @@ bool ARMDebuggerSetSoftwareBreakpoint(struct ARMDebugger* debugger, uint32_t add void ARMDebuggerClearBreakpoint(struct ARMDebugger* debugger, uint32_t address) { struct DebugBreakpoint** previous = &debugger->breakpoints; struct DebugBreakpoint* breakpoint; - for (; (breakpoint = *previous); previous = &breakpoint->next) { + struct DebugBreakpoint** next; + while ((breakpoint = *previous)) { + next = &breakpoint->next; if (breakpoint->address == address) { - *previous = breakpoint->next; + *previous = *next; free(breakpoint); } + previous = next; } } @@ -169,12 +172,15 @@ void ARMDebuggerSetWatchpoint(struct ARMDebugger* debugger, uint32_t address) { void ARMDebuggerClearWatchpoint(struct ARMDebugger* debugger, uint32_t address) { struct DebugWatchpoint** previous = &debugger->watchpoints; - struct DebugWatchpoint* breakpoint; - for (; (breakpoint = *previous); previous = &breakpoint->next) { - if (breakpoint->address == address) { - *previous = breakpoint->next; - free(breakpoint); + struct DebugWatchpoint* watchpoint; + struct DebugWatchpoint** next; + while ((watchpoint = *previous)) { + next = &watchpoint->next; + if (watchpoint->address == address) { + *previous = *next; + free(watchpoint); } + previous = next; } if (!debugger->watchpoints) { ARMDebuggerRemoveMemoryShim(debugger);