Fix Windows crashes and data corruption when flashing large ROMs - #10
Open
MaChInEgUn3 wants to merge 1 commit into
Open
Fix Windows crashes and data corruption when flashing large ROMs#10MaChInEgUn3 wants to merge 1 commit into
MaChInEgUn3 wants to merge 1 commit into
Conversation
Found while debugging why flashing a 6.8GB recovery ROM on Windows
reliably crashed or corrupted the transfer. All four issues below were
confirmed with a debug build against real hardware (POCO X7 Pro).
- validate_check(): post_buf is allocated just large enough for the
outgoing request, but is reused to hold the server's decoded/decrypted
response, which is usually bigger. Overflowed the heap buffer
(STATUS_HEAP_CORRUPTION on Windows) as soon as a response didn't fit.
- validate_check(): post_buf was free()'d right after the curl request
succeeded, but is read through json_create()'s in-place parsing for
the rest of the function - a use-after-free on every successful
request. This is likely the real root cause behind the heap
corruption above; the oversized buffer just changed how visibly it
crashed.
- validate_check() (choice 2, "ROMs that can be flashed"): tiny-json's
json_getSibling()/json_getName() dereference their argument without a
NULL check. A response object with 0 or 1 top-level property crashed
with a NULL pointer dereference.
- start_sideload(): the ROM file was opened in text mode ("r") instead
of binary ("rb"). On Windows this makes the CRT treat byte 0x1A as
EOF and rewrite CRLF sequences, corrupting whatever binary ROM data
follows the first occurrence.
- start_sideload(): file_size/block/offset/total_sent were `long`,
which is 32-bit on Windows (LLP64) even in a 64-bit build. Any ROM
over ~2GB - i.e. basically every recovery ROM this tool flashes -
overflows these, corrupting the sideload-host size announced to the
device and the per-chunk file offsets, aborting the transfer partway
through (observed as the device silently rebooting mid-flash).
Widened to 64-bit and switched to _fseeki64/_ftelli64 on Windows
(fseeko/ftello elsewhere) to seek past the 2GB mark correctly.
Tested end-to-end flashing a 6.3GB rodin_global recovery ROM on
Windows 11 after these fixes; completed successfully where the
unmodified build crashed or hung every time.
This was referenced Aug 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #7
Summary
While flashing a 6.8GB official recovery ROM (POCO X7 Pro,
rodin_global) on Windows, the tool consistently either crashed withSTATUS_HEAP_CORRUPTION(choice 2/3) or silently corrupted/aborted the sideload transfer partway through (device rebooting mid-flash). Bisected this down to four separate bugs inmiasst.c, all confirmed with a debug build against real hardware.Bugs fixed
validate_check()—post_bufis allocated only large enough for the outgoing request, but is reused to hold the server's decoded/decrypted response, which is usually larger. Overflows the heap buffer as soon as a response doesn't fit.validate_check()—post_bufwasfree()'d immediately after the curl request succeeded, but is still read (viajson_create()'s in-place parsing) for the rest of the function. This is probably the real root cause of the heap corruption above — the undersized buffer just changed how visibly it crashed.validate_check()(choice 2, "ROMs that can be flashed") —tiny-json'sjson_getSibling()/json_getName()dereference their argument with no NULL check. A response object with 0 or 1 top-level property crashes.start_sideload()— the ROM file was opened in text mode ("r") instead of binary ("rb"), which on Windows makes the CRT treat byte0x1Aas EOF and rewrite CRLF sequences mid-transfer. Separately,file_size/block/offset/total_sentwerelong, which is 32-bit on Windows (LLP64) even in a 64-bit build — any ROM over ~2GB (i.e. basically every recovery ROM this tool flashes) overflows these, corrupting the announced file size and per-chunk offsets and aborting the transfer partway through.Testing
Flashed a 6.3GB
rodin_globalrecovery ROM end-to-end on Windows 11 after these fixes; completed successfully (Installation_complete.) where the unmodified build crashed or hung on every attempt._fseeki64/_ftelli64are used on Windows;fseeko/ftelloare used elsewhere (Linux/macOS/Termux) to keep the fix portable across the platforms this project builds for.