Open tlyu opened 8 months ago
Updated #90.
Crash reporter excerpt:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Termination Reason: Namespace SIGNAL, Code 6 Abort trap: 6
Terminating Process: avarice [92774]
Application Specific Information:
abort() called
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x19af78744 __pthread_kill + 8
1 libsystem_pthread.dylib 0x19afafc28 pthread_kill + 288
2 libsystem_c.dylib 0x19aebdae8 abort + 180
3 libsystem_malloc.dylib 0x19addee28 malloc_vreport + 908
4 libsystem_malloc.dylib 0x19adf55d4 malloc_zone_error + 104
5 libsystem_malloc.dylib 0x19aded148 nanov2_guard_corruption_detected + 44
6 libsystem_malloc.dylib 0x19adec344 nanov2_allocate_outlined + 404
7 libc++abi.dylib 0x19af6a924 operator new(unsigned long) + 32
8 avarice 0x10009282c jtag3::sendFrame(unsigned char*, int) + 72
9 avarice 0x100093064 jtag3::sendJtagCommand(unsigned char*, int, char const*, unsigned char*&, int&) + 116
10 avarice 0x1000931d0 jtag3::doJtagCommand(unsigned char*, int, char const*, unsigned char*&, int&) + 64
11 avarice 0x1000964ac jtag3::jtagRead(unsigned long, unsigned int) + 892
12 avarice 0x1000a08c8 talkToGdb() + 1268
13 avarice 0x10009e5c8 main + 4088
14 dyld 0x19ac57f28 start + 2236
Diagnostics printed to terminal, which I wasn't able to capture by redirection:
avarice(92815,0x1f66fa100) malloc: Heap corruption detected, free list is damaged at 0x600000f78010
*** Incorrect guard value: 18446744071898212351
avarice(92815,0x1f66fa100) malloc: *** set a breakpoint in malloc_error_break to debug
[1] 92815 abort ~/src/avarice/src/avarice -d -w -C -4 localhost:6000
Target is an ATmega328P (Arduino Uno) connected to Atmel-ICE (also observed with AVR Dragon). Host is a MacBook Air M2 running macOS Ventura (also observed with an Intel MacBook Pro on an older OS).
Reading from flash via DebugWire can cause heap corruption on LP64 hosts, due to a confluence of errors. If the address would be a negative host
int
(typically0x80000000
or greater),chunksize
can get inappropriately reduced, leading to a very extended loop due to underflow/wraparound ofnumBytes
. This eventually causes host heap corruption as the loop attempts to write beyond the end of the flash cache.This demo required a patched avarice instrumented to show the intermediate values involved in the erroneous calculations. I used
netcat
to talk to avarice, because my previous reproducer was an older GDB plus an older version of avarice that didn't send memory maps (and thus allowed GDB to read from "negative" addresses).It's possible that a future GDB bug or newer target memory maps might allow this to happen.
It looped, continuing for over a hundred iterations. Eventually, this ended with:
remote.cc
callshexToInt
with a signedint addr
as the destination. It then callsjtagRead
, which takes anunsigned long
as the address. This causes sign extension while converting a negative number tounsigned long
. Thechunksize
adjustment calculations injtag3rw.cc
then increasechunksize
beyondnumBytes
, leading to the integer underflow/wraparound and buffer overflow.I have a patch in #90 that needs to be cleaned up and duplicated in
jtag3rw.cc
. (I created it when I first ran across this bug with AVR Dragon.)Full log:
overflow.txt