mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-10-01 17:18:19 +00:00
CMD_SPIFFS_DOWNLOAD read the whole file into BigBuf first. BigBuf_calloc() takes a uint16_t while the size is a uint32_t, so a 64K file allocated zero bytes and anything larger wrapped to a short buffer the file was then read straight past the end of. rdv40_spiffs_read_stream() opens the file once and hands out one frame at a time, so the size never reaches the allocator, and the SPIFFS path now honours start_index. Verified with an 80K round trip: upload, download, byte identical. The same BigBuf_calloc(filesize) wrap was in copy_in_spiffs(); it now copies in SPIFFS_WRITE_CHUNK_SIZE chunks. Separately, every flash failure was invisible. SPIFFS_CHECK_RES() only treats a negative result as an error and the HAL hooks returned 128/129/130, so SPIFFS saw success. The erase path was worst: Flash_Erase4k() only reports that the command was sent, both Flash_CheckBusy() results were discarded, and 'return (SPIFFS_OK == erased)' yields 1 on failure. A flash dump from a device that hit this showed one block written without being erased - its object index header held '0x14000 & 0x10000', and the filename ANDed away to empty. Erases are now read back and retried, and the HAL returns real SPIFFS error codes. Flash_Write() returned len unconditionally even after a rejected page, which also defeated the 'res == payload->len' check in CMD_FLASHMEM_WRITE. Feedback, so none of this is silent again: CMD_SPIFFS_WRITE answers with the SPIFFS result, the client aborts on the first refusal and names the byte it stopped at, dl_it() checks the terminator status, and both transfer directions print inline progress. Co-Authored-By: Claude Opus 5 (1M context)